1. 程式人生 > >NYOJ-1015(判斷是否為二分圖)

NYOJ-1015(判斷是否為二分圖)

二部圖
時間限制:1000 ms | 記憶體限制:65535 KB
難度:1
描述
二部圖又叫二分圖,我們不是求它的二分圖最大匹配,也不是完美匹配,也不是多重匹配,而是證明一個圖是不是二部圖。證明二部圖可以用著色來解決,即我們可以用兩種顏色去塗一個圖,使的任意相連的兩個頂點顏色不相同,切任意兩個結點之間最多一條邊。為了簡化問題,我們每次都從0節點開始塗色
輸入
輸入:
多組資料
第一行一個整數 n(n<=200) 表示 n個節點
第二行一個整數m 表示 條邊
隨後 m行 兩個整數 u , v 表示 一條邊
輸出
如果是二部圖輸出 BICOLORABLE.否則輸出 NOT BICOLORABLE.
樣例輸入
3
3
0 1
1 2
2 0
3
2
0 1
0 2
樣例輸出
NOT BICOLORABLE.
BICOLORABLE.

這是一個關於二分圖的判斷,就是判斷是否用兩種顏色把整張圖上色,並且相鄰的兩點顏色不能相同。這裡我用到的是DFS搜尋,我用了兩種存圖方式,完整程式碼如下

鄰接矩陣存圖法:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#define MAX_V 210
using namespace std;
int e[MAX_V][MAX_V];//這裡也可用bool型 
int color[MAX_V]; int V,E; bool dfs(int v,int c) { color[v] = c; for(int i=0;i<V;i++){ if(e[v][i] == 1 && color[i] == c) return false; if(e[v][i] == 1 && color[i] == 0 && !dfs(i,-c)) return false; /*注意這一步,不能分解,因為當該層的下一層,返回false時,到遞歸回到這一層仍要返回false。*/
} return true; } void solve() { if(!dfs(0,1)){//本題是從0這個節點來搜尋就可,但有些題目,圖可能不是聯通的,故要從頭到尾遍歷一遍。 printf("NOT BICOLORABLE.\n"); return; } printf("BICOLORABLE.\n"); return; } int main(void) { while(~scanf("%d",&V)){ scanf("%d",&E); memset(e,0,sizeof(e)); memset(color,0,sizeof(color)); int a,b; for(int i=0;i<E;i++) { scanf("%d %d",&a,&b); e[a][b] = 1;//由於是無向圖,故兩個都要存 e[b][a] = 1; } solve(); } return 0; }

不定長陣列,鄰接表存圖法

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<vector>
#include<cstdlib>
#define MAX_V 210
using namespace std;
vector<int>G[MAX_V];//這裡用不定長陣列,來存圖。 
int V,E,color[MAX_V];
bool dfs(int v,int c){
    color[v] = c;
    for(int i=0;i<G[v].size();i++){//連線這個節點的所有節點 
        if(color[G[v][i]] == c) return false;
        if(color[G[v][i]] == 0 && !dfs(G[v][i],-c)) return false;
        /*注意這一步,不能分解,因為當該層的下一層,返回false時,到遞歸回到這一層仍要返回false。*/ 
    }
    return true;
}
void solve()
{
    if(!dfs(0,1)){//本題是從0這個節點來搜尋就可,但有些題目,圖可能不是聯通的,故要從頭到尾遍歷一遍。 
        printf("NOT BICOLORABLE.\n");
        return;
    }

    printf("BICOLORABLE.\n");
    return;
}
int main(void)
{
    while(~scanf("%d",&V)){
        scanf("%d",&E);
        memset(color,0,sizeof(color));
        memset(G,0,sizeof(G));
        int a,b;
        for(int i=0;i<E;i++)
        {
            scanf("%d %d",&a,&b);//這裡是無向圖,要存存兩次,本人就在這裡WA了好多次,慚愧,一定細心。 
            G[a].push_back(b);
            G[b].push_back(a);
        }
        solve();
    }
    return 0;
}