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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

poj2186 求有向图G中所有点都能到达的点的数量

發布時間:2025/5/22 编程问答 95 豆豆
生活随笔 收集整理的這篇文章主要介紹了 poj2186 求有向图G中所有点都能到达的点的数量 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
/*題意:有向圖,求這樣的點的數量:所有點都能到達它.縮點成有向無環圖,思:如果該強連通有出度,那么 從該出度出去的邊必然回不來(已經縮點了),所以有出度的強連通必然不是。那么是不是所有出度為0的強連通 分量都是呢?顯然不是,如果存在多個出度為0的強連通,他們必然無解(他們之間必然不連通)。 任然遍歷邊,判斷不在一個連通分量中的邊(即為縮點后的邊)和點,考察期出度即可。*/ #include<iostream> //329ms,1A,基礎題。 #include<vector> #include<cstdio> #include<cstring> #include<stack> #include<queue> using namespace std; int n;int m; const int MAX=10001; vector<vector<int> >edges(MAX); int visited[MAX]; int low[MAX]; int dfn[MAX]; bool has_outd[MAX]; //是否有出度 int Strongly_connected_branch[MAX]; //并為一個強連通,標記為1.2.3... int num;int times; bool is_popular[MAX]; //整個強連通分支i是否有出度,其中一個點有即有 stack<int>s; bool instack[MAX]; int num_of_popular; //統計最終數量 void tarjan(int u) {low[u]=dfn[u]=times++;instack[u]=1;s.push(u);int len=edges[u].size();for(int i=0;i<len;i++){int v=edges[u][i];if(visited[v]==0) {visited[v]=1;tarjan(v);if(low[u]>low[v])low[u]=low[v];}else if(instack[v]&&low[u]>dfn[v]) //有向圖,要問是否在棧中,后向邊,V為U某個祖先{low[u]=dfn[v];}}if(dfn[u]==low[u]) //在一個SCC{num++;int temp;do{temp=s.top();instack[temp]=0;s.pop();Strongly_connected_branch[temp]=num;} while(temp!=u);} } void initialize() //初始化 {num_of_popular=num=times=0;for(int i=0;i<=n;i++){has_outd[i]=instack[i]=low[i]=dfn[i]=visited[i]=0;edges[i].clear();is_popular[i]=1;Strongly_connected_branch[i]=-1;} } bool readin() {scanf("%d",&n);scanf("%d",&m);initialize();int from,to;for(int i=1;i<=m;i++){scanf("%d%d",&from,&to);edges[from].push_back(to);}return 1; } void solve() {for(int i=1;i<=n;i++)if(visited[i]==0){visited[i]=1;tarjan(i);}for(int i=1;i<=n;i++) //自己思得:枚舉所有邊,縮點只是把所有SCC分開{int len=edges[i].size();for(int j=0;j<len;j++){int v=edges[i][j];if(Strongly_connected_branch[v]!=Strongly_connected_branch[i])//不在用一個強連通分支{has_outd[i]=1; //i所在強連通分量有出度is_popular[Strongly_connected_branch[i]]=0; //其所在強連通全跪!break;}}}queue<int>q;for(int i=1;i<=n;i++) //統計期所在強連通出度為0的點{if(is_popular[Strongly_connected_branch[i]]==0){continue;}if(has_outd[i]==0)q.push(i);}int te=Strongly_connected_branch[q.front()];while(!q.empty()) //判斷他們是否都在一個強連通中,否則跳出,無解。{int cur=q.front();if(te!=Strongly_connected_branch[cur]){printf("0\n");return;}num_of_popular++;q.pop();te=Strongly_connected_branch[cur];}printf("%d\n",num_of_popular); } int main() {readin();solve();return 0; }

轉載于:https://www.cnblogs.com/yezekun/p/3925814.html

總結

以上是生活随笔為你收集整理的poj2186 求有向图G中所有点都能到达的点的数量的全部內容,希望文章能夠幫你解決所遇到的問題。

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