P1330 封锁阳光大学
题目链接
刚看到题目,一脸懵逼,又不会,真的是图论刚入门(可能连门都没入),看了洛谷大佬题解,才知道这是一道染色的题目,每个相邻的点都要染成不同的颜色,我们只要两种颜色就可以了,最后算那种颜色用的少,就是答案。还有这图不一定连通。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,cnt;
int head[10010];
int sum[2];//0代表白色,1代表黑色,记录两种颜色的数量
bool vis[10010];//记录点是否染色
int she[10010];//记录每个点是什么颜色0或1
struct Node{
int to,next;
}edge[200010];
void add(int p,int q){
edge[cnt].to=q;
edge[cnt].next=head[p];
head[p]=cnt++;
}
bool dfs(int p,int q){//p代表点,q代表是什么颜色
if(vis[p]){//如果染色
if(she[p]==q){
return true;
}
else return false;
}
vis[p]=true;
sum[q]++;
she[p]=q;
bool f=true;
for(int i=head[p];~i;i=edge[i].next){
f=f&&dfs(edge[i].to,1-q);//颜色相反
}
return f;
}
int main(){
memset(head,-1,sizeof(head));
memset(she,-1,sizeof(she));
memset(vis,false,sizeof(vis));
scanf("%d%d",&n,&m);
int x,y;
int s=0;
for(int i=1;i<=m;i++){
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
for(int i=1;i<=n;i++){
if(vis[i]) continue;
if(dfs(i,0)){
s+=min(sum[0],sum[1]);
sum[0]=0;
sum[1]=0;
}
else{
printf("Impossible\n");
return 0;
}
}
printf("%d\n",s);
return 0;
}