二分圖判定HDU3478
阿新 • • 發佈:2018-11-07
判斷一個無向圖是否聯通並且不是二分圖
二分圖:二分圖又稱作二部圖,是圖論中的一種特殊模型。 設G=(V,E)是一個無向圖,如果頂點V可分割為兩個互不相交的子集(A,B),並且圖中的每條邊(i,j)所關聯的兩個頂點i和j分別屬於這兩個不同的頂點集(i in A,j in B),則稱圖G為一個二分圖。
簡而言之,就是頂點集V可分割為兩個互不相交的子集,並且圖中每條邊依附的兩個頂點都分屬於這兩個互不相交的子集,兩個子集內的頂點不相鄰。
https://blog.csdn.net/u013480600/article/details/30782257
#include<cstdio> #include<cstring> #include<vector> using namespace std; const int maxn=100000+10; const int maxm=500000+10; int n,m,s; vector<int> G[maxn]; int color[maxn]; int fa[maxn]; int find(int i) { if(fa[i]==-1) return i; return fa[i]=find(fa[i]); } bool bipartite(int u) { for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(color[v]==color[u]) return false; if(color[v]==0) { color[v]=3-color[u]; if(!bipartite(v)) return false; } } return true; } int main() { int T; scanf("%d",&T); for(int kase=1;kase<=T;kase++) { scanf("%d%d%d",&n,&m,&s); for(int i=0;i<n;i++) G[i].clear(); memset(color,0,sizeof(color)); memset(fa,-1,sizeof(fa)); for(int i=0;i<m;i++) { int u,v; scanf("%d%d",&u,&v); G[u].push_back(v); G[v].push_back(u); u=find(u), v=find(v); if(u!=v) fa[u]=v; } int cnt=0; //連通分量個數 for(int i=0;i<n;i++)if(find(i)==i) cnt++; if(cnt>1) { printf("Case %d: NO\n",kase); //這裡忘了Case %d了,WA了 continue; } bool sign=true; //存在完美時刻 color[s]=1; if(bipartite(s)) sign=false; printf("Case %d: %s\n",kase,sign?"YES":"NO"); } return 0; }