P1330 封锁阳光大学
作者:互联网
链接:P1330
--------------------------------
一道超级大坑题。
一开始我以为是再一个无图染色,结果竟然有一对不相通的子图。
而且还有单独一个点。
这样就麻烦了
---------------------------------
一个图染色,要求相邻的点颜色不相通,如果存在,那么把每个点的颜色颠倒也可以。
再这个图里我们就要这个做,运用bfs染色。
然而坑点就在于我们可以颠倒每一个子图的颜色,所以我们就要根据每一个子图去判断。
然后把每一个子图的最小加起来,就可以了
-------------------------------
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 using namespace std; 5 6 queue<int> q; 7 int head[1000001]; 8 struct b{ 9 int to; 10 int next; 11 }e[1000001]; 12 int x,y; 13 int vis[10000001]; 14 int color[100000]; 15 int n,m; 16 int p; 17 int f=1; 18 int cnt; 19 20 int dfs(){ 21 int ans=1;//统计子图的点数 22 int cntt=1;//染色数 23 while(q.size()){ 24 int flag=q.front(); 25 q.pop(); 26 for(int i=head[flag];i;i=e[i].next){ 27 int v=e[i].to; 28 if(!vis[v])//没拜访过就染色,统计 29 { 30 vis[v]=1; 31 cntt++; 32 color[v]=(!color[flag]); 33 if(color[v]==1) 34 ans++; 35 q.push(v); 36 } 37 else{//是否矛盾 38 if(color[v]==color[flag]){ 39 f=0; 40 return 0; 41 } 42 else 43 continue; 44 } 45 } 46 } 47 return min(ans,cntt-ans);//每一个子图的颜色 48 } 49 50 51 52 void add(int f,int to){ 53 p++; 54 e[p].next=head[f]; 55 e[p].to=to; 56 head[f]=p; 57 return ; 58 } 59 int anss; 60 int main(){ 61 cin>>n>>m; 62 for(int i=1;i<=m;++i){ 63 scanf("%d%d",&x,&y); 64 add(x,y); 65 add(y,x);//无向图 66 } 67 for(int i=1;i<=n;++i){ 68 if(!vis[i]){//如果没有被查过(新子图) 69 color[i]=1; 70 vis[i]=1;//单独一个点也要放 71 q.push(i); 72 anss+=dfs(); 73 } 74 } 75 if(f){ 76 cout<<anss; 77 } 78 else 79 cout<<"Impossible"; 80 return 0; 81 }Ac
标签:封锁,head,int,子图,flag,color,阳光,ans,P1330 来源: https://www.cnblogs.com/For-Miku/p/11268195.html