【题解】
注意这个图不保证联通。
对各个联通块尝试进行黑白染色,不能染色的话无解,可以染色的话选择点数较小的一部分加入到答案中。
【代码】
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long #define rg register #define N 200010 using namespace std; int n,m,tot,col[N],poi,cnt,ans,last[N]; bool ok=1; struct edge{ int to,pre; }e[N]; inline int read(){ int k=0,f=1; char c=getchar(); while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); return k*f; } void dfs(int now,int color){ if(!ok) return; poi++; if(color==1) cnt++; for(rg int i=last[now],to;i;i=e[i].pre) if(col[to=e[i].to]==-1) dfs(to,col[to]=color^1); else if(col[to=e[i].to]!=(color^1)){ ok=0; return; } } int main(){ n=read(); m=read(); for(rg int i=1;i<=n;i++) col[i]=-1; for(rg int i=1;i<=m;i++){ int u=read(),v=read(); e[++tot]=(edge){u,last[v]}; last[v]=tot; e[++tot]=(edge){v,last[u]}; last[u]=tot; } for(rg int i=1;i<=n;i++)if(col[i]==-1){ dfs(i,col[i]=poi=cnt=0); if(!ok) break; ans+=min(cnt,poi-cnt); // printf("[%d %d %d] ",i,poi,cnt); } if(ok) printf("%d ",ans); else puts("Impossible"); return 0; }