日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POJ2762(判断无向图的弱连通)

發布時間:2024/4/11 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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(判断无向图的弱连通)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。