POJ2762(判断无向图的弱连通)
生活随笔
收集整理的這篇文章主要介紹了
POJ2762(判断无向图的弱连通)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目:http://poj.org/problem?id=2762
?
題意:給出n個山洞,對于每個山洞,如果任意選擇兩點s,e,都滿足s可以到達e或者e可以到達s,則輸出Yes,否則輸出No。
?
分析:實際上判斷是否弱連通,所以首先強連通,然后縮點,對縮點形成的圖最多只能有一個入度為0的點,如果有多個入度為
0的點,則這兩個連通分量肯定是不連通的。縮點后形成的圖形是一棵樹,入度為0的點是這顆樹的根,這棵樹只能是單鏈,不
能有分叉,如果有分叉,則這些分叉之間是不可達的,所以就對這棵樹進行DFS,如果是單鏈則是YES。
?
#include <iostream> #include <string.h> #include <stdio.h>using namespace std; const int N = 10005;struct Edge {int to;Edge *next; };Edge *map1[N],*map2[N]; //分別保存原圖和縮點后的圖 int dfn[N],low[N],stack[N],belong[N],indeg[N]; int index,scc_num,top; bool tmp[N]; int result[N];void Tarjan(int u) {dfn[u] = low[u] = ++index;stack[++top] = u;tmp[u] = true;for(Edge *p = map1[u]; p; p = p->next) //枚舉每一條邊{int v = p->to;if(!dfn[v]){Tarjan(v); //dfs繼續下找low[u] = min(low[u],low[v]);}else if(tmp[v]){low[u] = min(low[u],dfn[v]);}}if(low[u] == dfn[u]) //如果節點u是強連通分量的根{int t;++scc_num; //強連通分量個數加1do{t = stack[top--];tmp[t] = false;belong[t] = scc_num; //記錄屬于第幾個強連通分量}while(t != u);} }int Count(int n) {for(int i=1;i<=n;i++)if(!dfn[i])Tarjan(i);return scc_num; }int Find() //在新圖中找入度為0的點,如果只有一個就返回位置,否則返回0 {int record;int cnt = 0;for(int i=1; i<=scc_num; i++){if(indeg[i] == 0){cnt++;record = i;}}if(cnt == 1) return record;return 0; }bool TopSort() {int u,num = 0;while(u = Find()){result[num++] = u;indeg[u] = -1;Edge *p = map2[u];while(p){indeg[p->to]--;p = p->next;}}if(num == scc_num) return true;return false; }void Init() {index = 0;top = 0;scc_num = 0;memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(indeg,0,sizeof(indeg));memset(tmp,false,sizeof(tmp));memset(map1,NULL,sizeof(map1));memset(map2,NULL,sizeof(map2));memset(result,0,sizeof(result)); }int main() {int T,m,n;scanf("%d",&T);while(T--){Init();scanf("%d%d",&n,&m);while(m--){int a,b;scanf("%d%d",&a,&b);Edge *p = new Edge();p->to = b;p->next = map1[a];map1[a] = p;}int cnt = Count(n);if(cnt == 1){puts("Yes");continue;}for(int i=1;i<=n;i++){Edge *p = map1[i];while(p){if(belong[i] != belong[p->to]){indeg[belong[p->to]]++;Edge *q = new Edge();q->to = belong[p->to];q->next = map2[belong[i]];map2[belong[i]] = q;}p = p->next;}}bool flag = false;int ans = 0;for(int i=1;i<=cnt;i++){if(indeg[i] == 0)ans++;}if(ans > 1) flag = false;else if(TopSort()) flag = true;if(flag) puts("Yes");else puts("No");}return 0; }
?
總結
以上是生活随笔為你收集整理的POJ2762(判断无向图的弱连通)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Codeforces344_C(数学思维
- 下一篇: POJ2236(并查集)