题目大意
题目:封锁阳光大学
思路解析
我们只需要将这张图黑白染色即可。
任选一个点,将其设为白色,进行一次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;
}