又刷了一道水题……
很显然只要判断这个图是否是二分图就行了,判断方法就是染色。如果对于边(u->v),两个点颜色相同,那么就说明图中存在奇环,不是二分图。
统计答案的时候输出两种颜色较小的就行了。
需要注意的是,图可能不连通,或者有些点不存在。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a, x) memset(a, x, sizeof(a)) 15 #define rg register 16 typedef long long ll; 17 typedef double db; 18 const int INF = 0x3f3f3f3f; 19 const db eps = 1e-8; 20 const int maxn = 1e4 + 5; 21 const int maxe = 1e5 + 5; 22 inline ll read() 23 { 24 ll ans = 0; 25 char ch = getchar(), last = ' '; 26 while(!isdigit(ch)) last = ch, ch = getchar(); 27 while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar(); 28 if(last == '-') ans = -ans; 29 return ans; 30 } 31 inline void write(ll x) 32 { 33 if(x < 0) x = -x, putchar('-'); 34 if(x >= 10) write(x / 10); 35 putchar(x % 10 + '0'); 36 } 37 38 int n, m, ans = 0; 39 struct Edge 40 { 41 int nxt, to; 42 }e[maxe << 1]; 43 int head[maxn], ecnt = -1; 44 void addEdge(int x, int y) 45 { 46 e[++ecnt] = (Edge){head[x], y}; 47 head[x] = ecnt; 48 } 49 50 int vis[maxn]; 51 int sta[maxn], top = 0; 52 void dfs(int now, int col) 53 { 54 sta[++top] = now; 55 vis[now] = col; 56 for(int i = head[now]; i != -1; i = e[i].nxt) 57 { 58 if(vis[e[i].to] == vis[now]) {puts("Impossible"); exit(0);} 59 if(vis[e[i].to]) continue; 60 dfs(e[i].to, col ^ 1); 61 } 62 } 63 64 int main() 65 { 66 Mem(head, -1); 67 n = read(); m = read(); 68 for(int i = 1; i <= m; ++i) 69 { 70 int x = read(), y = read(); 71 addEdge(x, y); addEdge(y, x); 72 } 73 for(int i = 1; i <= n; ++i) 74 { 75 if(!vis[i]) 76 { 77 dfs(i, 2); 78 int ans1 = 0, ans2 = 0; 79 while(top) 80 { 81 ans1 += (vis[sta[top]] == 2); 82 ans2 += (vis[sta[top]] == 3); 83 top--; 84 } 85 ans += min(ans1, ans2); 86 } 87 } 88 write(ans), enter; 89 return 0; 90 }