[洛谷]封锁阳光大学-图染色

题目大意

题目:封锁阳光大学

思路解析

我们只需要将这张图黑白染色即可。
任选一个点,将其设为白色,进行一次bfs,每个结点的邻接点都置成与其相反的颜色即可,如果一个点被置成了两种颜色,那么就是要输出Impossible。

程序注释

#include <iostream>
#include <queue>
#include <cstdlib>

using namespace std;
const int N=1e4+5,M=2e5+5;
int n,m;
int head[N],to[M],nxt[M],cnt;
int ans,blk,wht;
bool v[N];
int col[N];

void add(int x,int y) {
	to[++cnt]=y;
	nxt[cnt]=head[x];
	head[x]=cnt;
} 

void bfs(int s) {
	blk=0;wht=1;    //s点默认为白色,置为1
	queue<int> q;
	q.push(s);
	col[s]=2;
	while(!q.empty()) {
		int x=q.front();
		q.pop();
		v[x]=true;
		for(int i=head[x];i;i=nxt[i]) {
			int y=to[i];
			if(col[y]!=col[x]^1) {  //如果一节点有两种颜色
				cout<<"Impossible";
				exit(0);
			}
			if(!v[y]) {
				if(col[x]==2)   //颜色数增加
				  blk++;
				else
				  wht++;
				col[y]=col[x]^1;    //置位相反颜色
				q.push(y);
			}
		}
	}
}

int main() {
	cin>>n>>m;
	while(m--) {
		int x,y;
		cin>>x>>y;
		add(x,y);
		add(y,x);
	}
	for(int i=1;i<=n;i++)   //可能有多个连通块,需要像tarjan那样遍历完整张图
	  	if(!v[i]) {
	  		bfs(i);
	  		ans+=min(blk,wht);  //黑色白色选最少的
		}
	cout<<ans;
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/wyc06/p/13396347.html