hihoCoder #1121 : 二分圖一•二分圖斷定

#1121 : 二分圖一•二分圖斷定

Time Limit:10000ms
Case Time Limit:1000ms
Memory Limit:256MB

描述

你們好,我是小Hi和小Ho的小夥伴Nettle,從這個星期開始由我來完成咱們的Weekly。ios

新年回家,又到了一年一度大齡剩男剩女的相親時間。Nettle去姑姑家玩的時候看到了一張姑姑寫的相親狀況表,上面都是姑姑介紹相親的剩男剩女們。每行有2個名字,表示這兩我的有一場相親。因爲姑姑年齡比較大了記性不是太好,加上相親的人不少,因此姑姑一時也想不起來其中有些人的性別。所以她拜託我檢查一下相親表裏面有沒有錯誤的記錄,便是否把兩個同性安排了相親。算法

OK,讓咱們愉快的暴力搜索吧!ide

纔怪咧。spa

對於拿到的相親狀況表,咱們不妨將其轉化成一個圖。將每個人做爲一個點(編號1..N),若兩我的之間有一場相親,則在對應的點之間鏈接一條無向邊。(以下圖)code

由於相親老是在男女之間進行的,因此每一條邊的兩邊對應的人老是不一樣性別。假設表示男性的節點染成白色,女性的節點染色黑色。對於獲得的無向圖來講,即每一條邊的兩端必定是一白一黑。若是存在一條邊兩端同爲白色或者黑色,則表示這一條邊所表示的記錄有誤。blog

因爲咱們並不知道每一個人的性別,咱們的問題就轉化爲斷定是否存在一個合理的染色方案,使得咱們所創建的無向圖知足每一條邊兩端的頂點顏色都不相同ip

那麼,咱們不妨將全部的點初始爲未染色的狀態。隨機選擇一個點,將其染成白色。再以它爲起點,將全部相鄰的點染成黑色。再以這些黑色的點爲起點,將全部與其相鄰未染色的點染成白色。不斷重複直到整個圖都染色完成。(以下圖)string

在染色的過程當中,咱們應該怎樣發現錯誤的記錄呢?相信你必定發現了吧。對於一個已經染色的點,若是存在一個與它相鄰的已染色點和它的顏色相同,那麼就必定存在一條錯誤的記錄。(如上圖的4,5節點)it

到此咱們就獲得了整個圖的算法:io

 

  1. 選取一個未染色的點u進行染色
  2. 遍歷u的相鄰節點v:若v未染色,則染色成與u不一樣的顏色,並對v重複第2步;若v已經染色,若是 u和v顏色相同,斷定不可行退出遍歷。
  3. 若全部節點均已染色,則斷定可行。

接下來就動手寫寫吧!

輸入

第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」

Sample Input
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
Sample Output
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 }
View Code
相關文章
相關標籤/搜索