Description
K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即AB相互认识,BC相互认识,CA
相互认识,是简洁高效的.为了巩固三角关系,K国禁止四边关系,五边关系等等的存在.所谓N边关系,是指N个人 A1A2
...An之间仅存在N对认识关系:(A1A2)(A2A3)...(AnA1),而没有其它认识关系.比如四边关系指ABCD四个人 AB,BC,C
D,DA相互认识,而AC,BD不认识.全民比赛时,为了防止做弊,规定任意一对相互认识的人不得在一队,国王相知道,
最少可以分多少支队。
Input
第一行两个整数N,M。1<=N<=10000,1<=M<=1000000.表示有N个人,M对认识关系. 接下来M行每行输入一对朋
友
Output
输出一个整数,最少可以分多少队
Sample Input
4 5
1 2
1 4
2 4
2 3
3 4
1 2
1 4
2 4
2 3
3 4
Sample Output
3
HINT
一种方案(1,3)(2)(4)
这个实际上就是一个给弦图染色。。。
然后请参见
cdq的论文。。。。
然后关于mcs的O(n+m)的算法实现请参见
jcvb神犇详细的解答
1 #include<iostream> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<cstdio> 6 #include<algorithm> 7 #include<string> 8 #include<map> 9 #include<queue> 10 #include<vector> 11 #include<set> 12 #define inf 1000000000 13 #define maxn 10100 14 #define maxm 4004004 15 #define eps 1e-10 16 #define ll long long 17 #define for0(i,n) for(int i=0;i<=(n);i++) 18 #define for1(i,n) for(int i=1;i<=(n);i++) 19 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 20 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go) 22 using namespace std; 23 int read(){ 24 int x=0,f=1;char ch=getchar(); 25 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 26 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 27 return x*f; 28 } 29 struct edge{ 30 int go,next; 31 }e[maxm]; 32 int head[maxn],tot; 33 int n,m,ans,best,f[maxn],list[maxn],seq[maxn],color[maxn],mark[maxn]; 34 bool v[maxn]; 35 void add(int h[],int x,int y){ 36 e[++tot].go=y;e[tot].next=h[x]; 37 h[x]=tot; 38 } 39 void mcs(){ 40 int i,j; 41 for(int i=1;i<=n;i++)add(list,0,i); 42 for(j=n;j;j--){ 43 while(1){ 44 for(i=list[best];i;i=e[i].next){ 45 if(!v[e[i].go])break; 46 else list[best]=e[i].next; 47 } 48 if(i){ 49 int x=e[i].go; 50 v[x]=1;seq[j]=x; 51 for(i=head[x];i;i=e[i].next){ 52 if(!v[e[i].go]){ 53 f[e[i].go]++; 54 add(list,f[e[i].go],e[i].go); 55 best=max(best,f[e[i].go]); 56 } 57 } 58 break; 59 } 60 else best--; 61 } 62 } 63 } 64 int main(){ 65 //freopen("input.txt","r",stdin); 66 //freopen("output.txt","w",stdout); 67 int i,j,x,y; 68 n=read();m=read(); 69 for(i=1;i<=m;i++){ 70 x=read();y=read(); 71 add(head,x,y); 72 add(head,y,x); 73 } 74 mcs(); 75 for(j=n;j;j--){ 76 x=seq[j]; 77 for(i=head[x];i;i=e[i].next) 78 mark[color[e[i].go]]=j; 79 for(i=1;i<=n&&mark[i]==j;i++); 80 color[x]=i; 81 ans=max(ans,i); 82 } 83 printf("%d",ans); 84 return 0; 85 }