【图论】bnuoj 52810 Splitting the Empire

acm.bnu.edu.cn/v3/contest_show.php?cid=9208#problem/G

【题意】

  • 给定一个无向图,要求把这个无向图的点划分到不同的集合里,使得每个集合的点之间两两没有边相连
  • 求最少划分到多少个集合

【思路】

  • 相当于给一个图染色,相邻点染不同色(在不同集合),最少用多少种颜色
  • dfs染色,每个点选择能选择的编号最小的颜色

【AC】

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 
 5 const int maxn=5e4+2;
 6 const int maxm=1e6+2;
 7 int n,m,k;
 8 struct edge
 9 {
10     int to;
11     int nxt;
12 }e[maxm];
13 int head[maxn];
14 int tot;
15 bool vis[maxn];
16 int color[maxn];
17 bool tmp[maxn];
18 int ans;
19 void init()
20 {
21     memset(head,-1,sizeof(head));
22     tot=0;
23     ans=0;
24     memset(vis,false,sizeof(vis));
25     memset(color,0,sizeof(color));
26 }
27 
28 void add(int u,int v)
29 {
30     e[tot].to=v;
31     e[tot].nxt=head[u];
32     head[u]=tot++;
33 }
34 
35 void dfs(int u,int pa)
36 {
37     memset(tmp,false,sizeof(tmp));
38     for(int i=head[u];i!=-1;i=e[i].nxt)
39     {
40         int v=e[i].to;
41         tmp[color[v]]=true;
42     }
43     int c=-1;
44     for(int i=1;i<=n;i++)
45     {
46         if(!tmp[i])
47         {
48             c=i;
49             break;
50         }
51     }
52     color[u]=c;
53     ans=max(ans,c);
54     for(int i=head[u];i!=-1;i=e[i].nxt)
55     {
56         int v=e[i].to;
57         if(v==pa) continue;
58         if(vis[v]) continue;
59         vis[v]=true;
60         dfs(v,u);
61     }    
62 }
63 int main()
64 {
65     while(~scanf("%d%d",&n,&m))
66     {
67         init();
68         int u,v;
69         for(int i=1;i<=m;i++)
70         {
71             scanf("%d%d",&u,&v);
72             add(u,v);
73             add(v,u);
74         }
75     //    int flag=0;
76         for(int i=1;i<=n;i++)
77         {
78             if(!vis[i])
79             {
80                 vis[i]=true;
81                 dfs(i,-1);
82             }
83         }
84         cout<<ans<<endl;
85     }
86     return 0;
87 }
dfs

 

posted @ 2017-08-22 11:46  shulin15  阅读(243)  评论(0编辑  收藏  举报