【图论】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 }