题意:给定n个直线,保证无三线共点,将点染色,使得相邻两点颜色不同,最小化颜色数量
题解
这个图非常特殊,每个点度数最多为4,所以可以按照(x,y)排序,把两条边定为入边两条定为出边
选择一个点使得他与前两个点颜色不同即可
#include<bits/stdc++.h>
using namespace std;
const int maxn=1010;
const double eps=1e-8;
int sgn(double x){return (x>eps)-(x<-eps);}
struct P{
double x,y;
int id;
P(){}
P(double _x,double _y):x(_x),y(_y){}
double len(){return sqrt(x*x+y*y);}
void read(){scanf("%lf%lf",&x,&y);}
};
bool operator<(P a,P b){
return sgn(a.x-b.x) ? a.x < b.x : a.y < b.y;
}
P operator+(P a,P b){
return P(a.x+b.x,a.y+b.y);
}
P operator-(P a,P b){
return P(a.x-b.x,a.y-b.y);
}
P operator*(P a,double b){
return P(a.x*b,a.y*b);
}
P operator/(P a,double b){
return P(a.x/b,a.y/b);
}
double operator*(P a,P b){
return a.x*b.y-a.y*b.x;
}
double operator^(P a,P b){
return a.x*b.x+a.y*b.y;
}
double det(P a,P b,P c){
return (b-a)*(c-a);
}
struct L{
P a,b;
P v(){return b-a;}
}l[maxn];
bool parallel(L l1,L l2){
return sgn(l1.v()*l2.v())==0;
}
P intersect(L l1,L l2){
double s1=det(l1.a,l1.b,l2.a);
double s2=det(l1.a,l1.b,l2.b);
return (l2.a*s2-l2.b*s1)/(s2-s1);
}
vector<P>vec[maxn];
vector<int>G[maxn*maxn];
int col[maxn*maxn];
int in[maxn*maxn];
int n;
int mex(int x){
if(!(x>>0&1))return 1;
if(!(x>>1&1))return 2;
if(!(x>>2&1))return 4;
return -1;
}
int main(){
//FBI WARNING!!!!
//freopen("hdu5539.in","r",stdin);
//FBI WARNING!!!!
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
l[i].a.read();
l[i].b.read();
vec[i].clear();
}
int cur=0;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
cur++;
if(!parallel(l[i],l[j])){
P p=intersect(l[i],l[j]);
p.id=cur;
col[cur]=0;
in[cur]=0;
G[cur].clear();
vec[i].push_back(p);
vec[j].push_back(p);
//cout << i << " " << j <<endl;
}else col[cur]=-1;
}
}
for(int i=1;i<=n;i++)
sort(vec[i].begin(),vec[i].end());
for(int i=1;i<=n;i++){
for(int j=0;j+1<vec[i].size();j++){
G[vec[i][j].id].push_back(vec[i][j+1].id);
in[vec[i][j+1].id]++;
//cerr<<vec[i][j].id <<"->" << vec[i][j+1].id <<endl;
}
}
queue<int>q;
for(int i=1;i<=cur;i++)
if(!in[i]&&col[i]!=-1){
q.push(i);
col[i]=2;
}
while(!q.empty()){
int u=q.front();q.pop();
//printf("queue %d\n",u);
col[u]=mex(col[u]);
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
col[v]|=col[u];
if(!--in[v])
q.push(v);
}
}
cur=0;
int mxc=0;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
cur++;
int ans=-1;
if(col[cur]==-1)ans=-1;
else if(col[cur]>>0&1)ans=1;
else if(col[cur]>>1&1)ans=2;
else if(col[cur]>>2&1)ans=3;
mxc=max(mxc,ans);
}
}
cur=0;
printf("%d\n",mxc);
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
cur++;
int ans=-1;
if(col[cur]==-1)ans=-1;
else if(col[cur]>>0&1)ans=1;
else if(col[cur]>>1&1)ans=2;
else if(col[cur]>>2&1)ans=3;
printf("%d%c",ans," \n"[j==n]);
}
}
}
return 0;
}