曹是一隻愛刷街的老曹,暑假期間,他天天都歡快地在陽光大學的校園裏刷街。河蟹看到歡快的曹,感到不爽。河蟹決定封鎖陽光大學,不讓曹刷街。html
陽光大學的校園是一張由N個點構成的無向圖,N個點之間由M條道路鏈接。每隻河蟹能夠對一個點進行封鎖,當某個點被封鎖後,與這個點相連的道路就被封鎖了,曹就沒法在與這些道路上刷街了。很是悲劇的一點是,河蟹是一種不和諧的生物,當兩隻河蟹封鎖了相鄰的兩個點時,他們會發生衝突。前端
詢問:最少須要多少隻河蟹,能夠封鎖全部道路而且不發生衝突。ios
第一行:兩個整數N,M數組
接下來M行:每行兩個整數A,B,表示點A到點B之間有道路相連。spa
僅一行:若是河蟹沒法封鎖全部道路,則輸出「Impossible」,不然輸出一個整數,表示最少須要多少隻河蟹。code
3 3 1 2 1 3 2 3
Impossible
3 2 1 2 2 3
1
【數據規模】orm
1<=N<=10000,1<=M<=100000,任意兩點之間最多有一條道路。htm
本題其實是一道二分圖的題目。blog
若是咱們把圖中U、V兩個集合中的全部連線都用河蟹斷開,就達到了題目要求。要判斷圖中的二分圖,只須要相似01迷宮進行BFS遍歷染色便可。在染色的過程當中,若是發現連線的另外一個端點未染色,就用和當前端點不一樣的顏色染色,要是已經染色且和當前節點顏色相同,就說明構成循環圈,不能構成二分圖,相似下圖的狀況。ci
代碼以下:
1 #include <iostream> 2 #include <math.h> 3 #include <stdio.h> 4 #include <algorithm> 5 #include <string.h> 6 7 using namespace std; 8 9 const int MAXN = 100005; 10 int first[MAXN], n, m, en, color[MAXN], f[2], u, v; //f統計不一樣顏色節點數 11 int front, rear; 12 bool vis[MAXN]; 13 int ans; 14 15 struct edge 16 { 17 int zhongdian, changdu; 18 int next; 19 }; 20 21 edge ed[MAXN]; 22 23 void add_edge(int s, int e, int d) 24 { 25 en++; 26 ed[en].next = first[s]; 27 first[s] = en; 28 ed[en].zhongdian = e; 29 ed[en].changdu = d; 30 } 31 32 struct Node 33 { 34 int x, y; 35 int step; 36 }; 37 Node q[MAXN]; 38 39 int bfs(int a) 40 { 41 Node now, next; 42 now.x = a; 43 vis[a] = 1; 44 color[a] = 1; 45 f[0] = 0; 46 f[1] = 1; 47 front = rear = 0; 48 q[rear] = now; 49 rear++; 50 while(front < rear) 51 { 52 now = q[front++]; 53 for(int i = first[now.x]; i; i = ed[i].next) 54 //first[now]:當前點的第一條邊;ed[i].next:下一個訪問的點 55 { 56 if(color[ed[i].zhongdian] != -1) 57 { 58 if(color[ed[i].zhongdian] == color[now.x]) 59 { 60 cout << "Impossible" << endl; 61 return -1; 62 } 63 } 64 else 65 { 66 color[ed[i].zhongdian] = (color[now.x] + 1) % 2; 67 q[rear].x = ed[i].zhongdian; 68 rear++; 69 f[color[ed[i].zhongdian]]++; 70 } 71 } 72 } 73 ans += min(f[0], f[1]); 74 } 75 76 int main() 77 { 78 cin >> n >> m; 79 for(int i = 1; i <= n; i++) 80 { 81 color[i] = -1; //初始化 82 } 83 for(int i = 1; i <= m; i++) 84 { 85 cin >> u >> v; 86 add_edge(u, v, 0); 87 add_edge(v, u, 0); 88 } 89 for(int i = 1; i <= n; i++) 90 { 91 if(color[i] == -1) 92 { 93 if(bfs(i) < 0) 94 { 95 return 0; 96 } 97 } 98 } 99 cout << ans << endl; 100 101 return 0; 102 }
代碼中的f數組是用來統計黑白兩種染色點的個數的,本題所求的最小河蟹數就是兩種染色點個數的最小值。