NYOJ-1015(判斷是否為二分圖)
阿新 • • 發佈:2019-01-23
二部圖
時間限制: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;
}