这是一道神坑题!
刚开始看了题还以为是Tarjan(我也不知道Tarjan有什么用)。
然后发现这是染色问题的模板题!
找到没有染色的点,然后将它涂成1(一共只有1,2两种颜色)
与它相连的点进行广搜,如果没有颜色染成与它不同的颜色。
如果已经有颜色且颜色相同,输出impossible。
然后两个颜色取最小值累加即可。
CODE
#include<bits/stdc++.h> using namespace std; inline void read(int &x) { x=0; char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); } const int N=10005,M=100005; vector <int> a[N]; int col[N],n,m,x,y,i,ans,q[N*2+10]; void bfs(int x) { col[x]=1; int c1=1,c2=0,head=0,tail=1; q[1]=x; while (head<tail) { int now=q[++head]; for (int i=0;i<a[now].size();++i) { int k=a[now][i]; if (col[k]==0) { if (col[now]==1) { col[k]=2; c2++; } else { col[k]=1; c1++; } q[++tail]=k; } else if (col[k]==col[now]) { puts("Impossible"); exit(0); } } } ans+=min(c1,c2); } int main() { read(n); read(m); for (i=1;i<=m;++i) { read(x); read(y); a[x].push_back(y); a[y].push_back(x); } for (i=1;i<=n;++i) if (!col[i]) bfs(i); printf("%d",ans); return 0; }
至于为什么要开万能头文件,因为我不知道exit()的库。