你們好,我是小Hi和小Ho的小夥伴Nettle,從這個星期開始由我來完成咱們的Weekly。ios
新年回家,又到了一年一度大齡剩男剩女的相親時間。Nettle去姑姑家玩的時候看到了一張姑姑寫的相親狀況表,上面都是姑姑介紹相親的剩男剩女們。每行有2個名字,表示這兩我的有一場相親。因爲姑姑年齡比較大了記性不是太好,加上相親的人不少,因此姑姑一時也想不起來其中有些人的性別。所以她拜託我檢查一下相親表裏面有沒有錯誤的記錄,便是否把兩個同性安排了相親。算法
OK,讓咱們愉快的暴力搜索吧!ide
纔怪咧。spa
對於拿到的相親狀況表,咱們不妨將其轉化成一個圖。將每個人做爲一個點(編號1..N),若兩我的之間有一場相親,則在對應的點之間鏈接一條無向邊。(以下圖)code
由於相親老是在男女之間進行的,因此每一條邊的兩邊對應的人老是不一樣性別。假設表示男性的節點染成白色,女性的節點染色黑色。對於獲得的無向圖來講,即每一條邊的兩端必定是一白一黑。若是存在一條邊兩端同爲白色或者黑色,則表示這一條邊所表示的記錄有誤。blog
因爲咱們並不知道每一個人的性別,咱們的問題就轉化爲斷定是否存在一個合理的染色方案,使得咱們所創建的無向圖知足每一條邊兩端的頂點顏色都不相同。ip
那麼,咱們不妨將全部的點初始爲未染色的狀態。隨機選擇一個點,將其染成白色。再以它爲起點,將全部相鄰的點染成黑色。再以這些黑色的點爲起點,將全部與其相鄰未染色的點染成白色。不斷重複直到整個圖都染色完成。(以下圖)string
在染色的過程當中,咱們應該怎樣發現錯誤的記錄呢?相信你必定發現了吧。對於一個已經染色的點,若是存在一個與它相鄰的已染色點和它的顏色相同,那麼就必定存在一條錯誤的記錄。(如上圖的4,5節點)it
到此咱們就獲得了整個圖的算法:io
接下來就動手寫寫吧!
第1行:1個正整數T(1≤T≤10)
接下來T組數據,每組數據按照如下格式給出:
第1行:2個正整數N,M(1≤N≤10,000,1≤M≤40,000)
第2..M+1行:每行兩個整數u,v表示u和v之間有一條邊
第1..T行:第i行表示第i組數據是否有誤。若是是正確的數據輸出」Correct」,不然輸出」Wrong」
2 5 5 1 2 1 3 3 4 5 2 1 5 5 5 1 2 1 3 3 4 5 2 3 5
Wrong Correct
解題:二分圖判斷。。。
1 /* 2 @author: Lev 3 @date: 4 */ 5 #include <iostream> 6 #include <cstdio> 7 #include <cmath> 8 #include <cstring> 9 #include <string> 10 #include <cstdlib> 11 #include <algorithm> 12 #include <map> 13 #include <set> 14 #include <queue> 15 #include <climits> 16 #include <deque> 17 #include <sstream> 18 #include <fstream> 19 #include <bitset> 20 #include <iomanip> 21 #define LL long long 22 #define INF 0x3f3f3f3f 23 24 using namespace std; 25 struct arc { 26 int to,next; 27 arc(int x = 0,int y = -1) { 28 to = x; 29 next = y; 30 } 31 }; 32 arc e[500000]; 33 int head[100000],color[100000],tot,n,m; 34 void add(int u,int v) { 35 e[tot] = arc(v,head[u]); 36 head[u] = tot++; 37 } 38 queue<int>q; 39 bool bfs(int x) { 40 while(!q.empty()) q.pop(); 41 q.push(x); 42 color[x] = 1; 43 while(!q.empty()) { 44 int u = q.front(); 45 q.pop(); 46 for(int i = head[u]; ~i; i = e[i].next) { 47 if(color[e[i].to]) { 48 if(color[e[i].to] == color[u]) return false; 49 } else { 50 color[e[i].to] = -1*color[u]; 51 q.push(e[i].to); 52 } 53 } 54 } 55 return true; 56 } 57 int main() { 58 int kase; 59 scanf("%d",&kase); 60 while(kase--) { 61 scanf("%d %d",&n,&m); 62 memset(head,-1,sizeof(head)); 63 memset(color,0,sizeof(color)); 64 for(int i = tot = 0; i < m; ++i) { 65 int u,v; 66 scanf("%d %d",&u,&v); 67 add(u,v); 68 add(v,u); 69 } 70 bool ans = true; 71 for(int i = 1; i <= n; ++i) 72 if((!color[i]) && (ans = bfs(i))) continue; 73 else break; 74 printf("%s\n",ans?"Correct":"Wrong"); 75 } 76 return 0; 77 }