封锁阳光大学-二分图染色
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了封锁阳光大学-二分图染色相关的知识,希望对你有一定的参考价值。
http://www.luogu.org/problem/show?pid=1330
题目描述
曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街。河蟹看到欢快的曹,感到不爽。河蟹决定封锁阳光大学,不让曹刷街。
阳光大学的校园是一张由N个点构成的无向图,N个点之间由M条道路连接。每只河蟹可以对一个点进行封锁,当某个点被封锁后,与这个点相连的道路就被封锁了,曹就无法在与这些道路上刷街了。非常悲剧的一点是,河蟹是一种不和谐的生物,当两只河蟹封锁了相邻的两个点时,他们会发生冲突。
询问:最少需要多少只河蟹,可以封锁所有道路并且不发生冲突。
输入输出格式
输入格式:
第一行:两个整数N,M
接下来M行:每行两个整数A,B,表示点A到点B之间有道路相连。
输出格式:
仅一行:如果河蟹无法封锁所有道路,则输出“Impossible”,否则输出一个整数,表示最少需要多少只河蟹。
对图进行染色(数据中一个图可能有不止一个连通块),失败就输出无解,成功就累加染色点数较小的颜色(用1和2表示)
1 #include<iostream> 2 #include<cstring> 3 #include<vector> 4 using namespace std; 5 const int inf=1<<30; 6 const int maxn=10000+10; 7 struct Edge{ 8 int go,next; 9 }; 10 vector<Edge> edges; 11 vector<int> G[maxn]; 12 int end[maxn],color[maxn],count[3],n,m,from,to; 13 void init(){ 14 memset(end,0,sizeof(end)); 15 memset(color,0,sizeof(color)); 16 count[1]=count[2]=0; 17 } 18 void add(int from,int to){ 19 Edge e;e.next=end[from],e.go=to;edges.push_back(e);end[from]=edges.size()-1; 20 } 21 bool dfs(int u) 22 { 23 for(/*int i=end[u];i;i=edges[i].next*/int i=0;i<G[u].size();i++){ 24 //int go=edges[i].go; 25 int go=G[u][i]; 26 if(color[u]==color[go]) return false; 27 if(!color[go]){ 28 color[go]=3-color[u],count[color[go]]++; 29 if(!dfs(go)) return false; 30 } 31 } 32 return true; 33 } 34 int main() 35 { 36 init(); 37 int ans=0; 38 cin>>n>>m; 39 for(int i=1;i<=m;i++){ 40 cin>>from>>to; 41 //add(from,to),add(to,from); 42 G[from].push_back(to); 43 G[to].push_back(from); 44 } 45 for(int i=1;i<=n;i++) if(!color[i]){ 46 color[i]=1; 47 count[1]++; 48 if(!dfs(i)){ 49 cout<<"Impossible";return 0; 50 } 51 ans+=min(count[1],count[2]); 52 count[1]=count[2]=0; 53 } 54 cout<<ans; 55 return 0; 56 }
以上是关于封锁阳光大学-二分图染色的主要内容,如果未能解决你的问题,请参考以下文章