并查集問題。給出n個點n對連接關系
我們需要判斷它是否能夠構成一個類似圓的圖形(帶邊的封閉圖形)
這個時候我們需要用并查集
并查集記得加路徑優化
我們需要知道封閉圖形每個點只能與兩個點相連。
而且這個封閉圖形由n個點組成
Your task is so easy. I will give you an undirected graph, and you just need to tell me whether the graph is just a circle. A cycle is three or more nodes V1, V2, V3, ... Vk, such that there are edges between V1 and V2, V2 and V3, ... Vk and V1, with no other extra edges. The graph will not contain self-loop. Furthermore, there is at most one edge between two nodes.
InputThere are multiple cases (no more than 10).
The first line contains two integers n and m, which indicate the number of nodes and the number of edges (1 < n < 10, 1 <= m < 20).
Following are m lines, each contains two integers x and y (1 <= x, y <= n, x != y), which means there is an edge between node x and node y.
There is a blank line between cases.
OutputIf the graph is just a circle, output "YES", otherwise output "NO".
Sample Input3 31 22 31 34 41 22 33 11 4Sample OutputYESNO上代碼#include<stdio.h>#include<string.h>#include<stdlib.h>#include<algorithm>#include<iostream>#include<ctype.h>#include<stack>#include<queue>using namespace std;int f[1003],num[1003],ans[1003];int join(int x){ return (x==f[x])?x:join(f[x]);//并查集的查,外加路徑壓縮}void coin(int x,int y)//并{ int xx=join(x); int yy=join(y); if(xx!=yy) { ans[xx]+=ans[yy];//每次建立新的聯系祖先點都需要將分支點的所包含的子點數加起來
f[yy]=xx; }}
//我們需要記錄每個點出現的次數
//我們需要借助祖先點
int main(){ int n,m; while(~scanf("%d%d",&n,&m)) { int flag=0; memset(num,0,sizeof(num)); for(int i=1; i<=n; i++)f[i]=i,ans[i]=1; int a,b; for(int i=0; i<m; i++) { scanf("%d%d",&a,&b); if(a==b) { flag=1; } num[a]++; num[b]++; coin(a,b); } for(int i=1; i<=n; i++) { int z=join(i); if(num[i]!=2||ans[z]!=n) { //PRintf("%d %d/n",i,ans[z]); flag=1; break; } } if(flag) printf("NO/n"); else printf("YES/n"); }}
新聞熱點
疑難解答