Luogu1330封锁阳光大学(二分图染色、搜索)
【题干】
阳光大学的校园是一张由N个点构成的无向图,N个点之间由M条道路连接。每只河蟹可以对一个点进行封锁,当某个点被封锁后,与这个点相连的道路就被封锁了,曹就无法在与这些道路上刷街了。非常悲剧的一点是,河蟹是一种不和谐的生物,当两只河蟹封锁了相邻的两个点时,他们会发生冲突。
询问:最少需要多少只河蟹,可以封锁所有道路并且不发生冲突。
【解题】
二分图染色。
因为可能不连通所以要遍历每个点,记得数组初始化。
学一学换颜色和结束函数的骚操作。
#include<bits/stdc++.h> using namespace std; const int N = 500005; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); return x * f; } int n,m,a,b,len,x,t, ans; int head[N],c[N],vis[N]; struct node{ int v,next; }e[N]; inline void adde(int u, int v){ e[++len].next = head[u]; head[u] = len; e[len].v = v; } void dfs(int wqy,int t){ if(c[wqy] != -1 && c[wqy] != t){ printf("Impossible"); exit(0); } if(c[wqy] == t) return ; x++; c[wqy] = t; vis[wqy] = 1; for(int i = head[wqy]; i; i = e[i].next) { int v = e[i].v; dfs(v,t^1); } } int main(){ n = read(), m = read(); for(register int i = 1; i <= m; ++i){ a = read(), b = read(); adde(a,b); adde(b,a); } for(int i = 1; i <= n; i++){ //每个点都要遍历因为图可能不连通 if(!vis[i]){ memset(c,-1,sizeof c); t = 0, x = 0; dfs(i,0); t = 0; for(register int i = 1; i <= n; ++i) t += (c[i] == 0); ans += min(t,x-t); } } printf("%d\n",ans); return 0; }
满堂花醉三千客,一剑霜寒十四州