BZOJ1006:[HNOI2008]神奇的国度(弦图染色)

Description

K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即AB相互认识,BC相互认识,CA相互认识,是简洁高效的.

为了巩固三角关系,K国禁止四边关系,五边关系等等的存在.所谓N边关系,是指N个人 A1A2...An之间仅存在N对认识关系:(A1A2)(A2A3)...(AnA1),而没有其它认识关系.

比如四边关系指ABCD四个人 AB,BC,CD,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

Sample Output

3

HINT

一种方案(1,3)(2)(4)

Solution

弦图染色流程:

初始把所有点的$ID$标为$0$。

每次从没删除的点中取$ID$最大的点$x$,让与$x$相连的点$ID++$,同时删除$x$点。

我用了个$set$维护复杂度也许是$nlogn$的。

Code

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<set>
 5 #define N (10009)
 6 using namespace std;
 7 
 8 struct Edge{int to,next;}edge[N*200];
 9 int n,m,ans,vis[N],ID[N];
10 int head[N],num_edge;
11 set<pair<int,int> >s;
12 set<pair<int,int> >::iterator it;
13 
14 inline int read()
15 {
16     int x=0,w=1; char c=getchar();
17     while (c<'0' || c>'9') {if (c=='-') w=-1; c=getchar();}
18     while (c>='0' && c<='9') x=x*10+c-'0', c=getchar();
19     return x*w;
20 }
21 
22 void add(int u,int v)
23 {
24     edge[++num_edge].to=v;
25     edge[num_edge].next=head[u];
26     head[u]=num_edge;
27 }
28 
29 int main()
30 {
31     n=read(); m=read();
32     for (int i=1; i<=m; ++i)
33     {
34         int u=read(),v=read();
35         add(u,v); add(v,u);
36     }
37     for (int i=1; i<=n; ++i) s.insert(make_pair(0,i));
38     while (!s.empty())
39     {
40         it=s.end(); it--; s.erase(it);
41         int x=(*it).second; vis[x]=1;
42         for (int i=head[x]; i; i=edge[i].next)
43             if (!vis[edge[i].to])
44             {
45                 s.erase(make_pair(ID[edge[i].to],edge[i].to));
46                 s.insert(make_pair(++ID[edge[i].to],edge[i].to));
47             }
48     }
49     for (int i=1; i<=n; ++i) ans=max(ans,ID[i]+1);
50     printf("%d\n",ans);
51 }
posted @ 2019-03-02 09:28  Refun  阅读(169)  评论(0编辑  收藏  举报