poj2186Popular Cows(Kosaraju算法--有向圖的強連通分量的分解)

 1 /*
 2    題目大意:有N個cows, M個關系
 3    a->b 表示 a認為b  popular;如果還有b->c, 那么就會有a->c 
 4    問最終有多少個cows被其他所有cows認為是popular!
 5    
 6    思路:強連通分量中每兩個節點都是可達的! 通過分解得到最后一個連通分量A,
 7    如果將所有的強連通分量看成一個大的節點,那么A一定是孩子節點(因為我們先
 8    完成的是父親節點的強連通分量)! 最后如果其他的強連通分量都可以指向A,那么
 9    A中的每一個cow都會被其他cows所有的cows認為popular! 
10 */ 
11 #include <string>
12 #include <cstdio>
13 #include <cstring>
14 #include <iostream>
15 #include<vector>
16 #define M 10005
17 using namespace std;
18 
19 vector<int>ex[M];
20 vector<int>ey[M];
21 
22 int n, m;
23 int cnt[M];//記錄第一次dfs的節點的逆序
24 int vis[M];//標記節點是否已經被訪問過了
25 int mark[M];//標記每一個節點是屬于哪一個連通分量
26 int ans;
27 int top;
28 
29 void dfs1(int u){//出度遍歷 
30     if(!vis[u]){
31        vis[u]=1;
32        int len=ex[u].size();
33        for(int i=0; i<len; ++i){
34            int v=ex[u][i];
35            dfs1(v);
36        }
37        cnt[top++]=u;
38     }
39 }
40 
41 void dfs2(int u){//入度遍歷 
42    if(!vis[u]){
43       vis[u]=1;
44       mark[u]=ans;
45       int len=ey[u].size();
46       for(int i=0; i<len; ++i){
47          int v=ey[u][i];
48          dfs2(v);
49       }
50    }
51 }
52 
53 int main(){
54    while(scanf("%d%d", &n, &m)!=EOF){
55       while(m--){
56          int u, v;
57          scanf("%d%d", &u, &v);
58          ex[u].push_back(v);
59          ey[v].push_back(u);
60       }
61       ans=top=0;
62       for(int i=1; i<=n; ++i)
63          if(!vis[i])
64              dfs1(i);
65       
66       memset(vis, 0, sizeof(vis));
67 
68       for(int i=top-1; i>=0;  --i)
69           if(!vis[cnt[i]]){
70              ++ans;
71              dfs2(cnt[i]);
72           }
73       int count=0;
74       int u=0;
75       for(int i=1; i<=n; ++i)
76            if(mark[i]==ans){
77               ++count;
78               u=i;
79            }
80       memset(vis, 0, sizeof(vis));
81       dfs2(u);
82 
83       for(int i=1; i<=n; ++i)//其他的強連通分量是否都指向了最后一個強連通分量 
84         if(!vis[i]){
85            count=0;
86            break;
87         }
88       printf("%d\n", count);
89       for(int i=1; i<=n; ++i){
90          ex[i].clear();
91          ey[i].clear();
92       }
93       memset(vis, 0, sizeof(vis));
94    }
95    return 0;
96 }

 1 /*
 2 tarjan 算法果然nb! 首先我們利用該算法將所有的強連通分量分開!
 3 然后將每一個連通分量看成是一個點,這樣就成了一個有向無環圖!
 4 接著判斷初度為 0 的點一共有多少個!如果只有一個,那么最終的答案就是
 5 這個節點終所有子節點的個數!也就是說這個節點中的每一個子節點都能 
 6 其他的所有節點到達!
 7 
 8 如果初度為 0 的點多余1個,那么對不起,不能滿足某個節點恰好能被其他所有
 9 的節點訪問到! 
10 */#include<iostream>
11 #include<cstdio>
12 #include<vector>
13 #include<stack>
14 #include<cstring>
15 #define M 10005
16 using namespace std;
17 
18 vector<int>edge[M];
19 stack<int>s;
20 int low[M], vis[M];
21 int sccN[M], pre[M];
22 int n, m;
23 int dfs_clock, cnt;
24 
25 void dfs(int u){//tarjan 算法 
26    int len = edge[u].size();
27    pre[u]=low[u]=++dfs_clock;
28    s.push(u);
29    for(int i=0; i<len; ++i){
30        int v=edge[u][i];
31        if(!pre[v]){
32           dfs(v);
33           low[u]=min(low[u], low[v]);            
34        } 
35        else if(!sccN[v])
36           low[u] = min(low[u], pre[v]);  
37    }     
38    if(low[u]==pre[u]){
39        ++cnt;
40        while(1){
41          int v=s.top();
42          s.pop();
43          sccN[v]=cnt;
44          if(u==v) break;
45        }           
46    }
47 }
48 
49 int main(){
50    while(scanf("%d%d", &n, &m)!=EOF){
51        dfs_clock=cnt=0;
52        memset(pre, 0, sizeof(pre));
53        memset(sccN, 0, sizeof(sccN));
54        memset(vis, 0, sizeof(vis));
55        while(m--){
56           int u, v;
57           scanf("%d%d", &u, &v);
58           edge[u].push_back(v);           
59        }   
60        for(int i=1; i<=n; ++i)
61           if(!pre[i]) 
62              dfs(i);
63        int num=0;    
64        for(int i=1; i<=n; ++i)
65           if(sccN[i]==1)
66              ++num;
67        int count=0;
68        memset(vis, 0, sizeof(vis));
69        for(int i=1; i<=n; ++i){
70            int len=edge[i].size();
71            for(int j=0; j<len; ++j)
72               if(sccN[i] != sccN[edge[i][j]]){
73                  vis[sccN[i]]=1;
74                  break;
75               }        
76        }
77        
78        for(int i=1; i<=cnt; ++i)
79          if(!vis[i]) ++count;
80        if(count==1)
81           printf("%d\n", num);
82        else printf("0\n");
83        for(int i=1; i<=n; ++i)
84           edge[i].clear();
85        while(!s.empty())
86           s.pop();
87    }
88    return 0;    
89 }
  1 /*比較慢的方法就是:利用tarjan算法將所有的強連通分量進行分離之后,
  2  將每一個強連通分量看成是一個點,如果有滿足我們答案的解,那么初度為零
  3  點一定只有一個,并且這個點的所有子節點的編號是 1!那么我們先計算出子節點
  4  編號為 1的個數, 然后在判斷其他的強連通分量的節點是否能夠到達編號為 1 的
  5  強連通分量! */
  6 #include<iostream>
  7 #include<cstdio>
  8 #include<vector>
  9 #include<stack>
 10 #include<cstring>
 11 #define M 10005
 12 using namespace std;
 13 
 14 vector<int>edge[M];
 15 stack<int>s;
 16 int low[M], vis[M], used[M];
 17 int sccN[M], pre[M];
 18 int n, m;
 19 int dfs_clock, cnt, sum, xx;
 20 
 21 void dfs(int u){
 22    int len = edge[u].size();
 23    pre[u]=low[u]=++dfs_clock;
 24    s.push(u);
 25    for(int i=0; i<len; ++i){
 26        int v=edge[u][i];
 27        if(!pre[v]){
 28           dfs(v);
 29           low[u]=min(low[u], low[v]);            
 30        } 
 31        else if(!sccN[v])
 32           low[u] = min(low[u], pre[v]);  
 33    }     
 34    if(low[u]==pre[u]){
 35        ++cnt;
 36        while(1){
 37          int v=s.top();
 38          s.pop();
 39          sccN[v]=cnt;
 40          if(u==v) break;
 41        }           
 42    }
 43 }
 44 
 45 int dfs2(int u){
 46     int len=edge[u].size();
 47     if(sccN[u]==1){//到達之后就不在進行任何搜索 
 48        sum+=xx;
 49        return 1;         
 50     }
 51     vis[u]=1;
 52     for(int i=0; i<len; ++i){
 53        int v=edge[u][i];
 54        if(!vis[v]){
 55            if(dfs2(v))
 56              return 1;      
 57        }
 58     }     
 59    return 0;
 60 }
 61 
 62 int main(){
 63    while(scanf("%d%d", &n, &m)!=EOF){
 64        dfs_clock=cnt=0;
 65        memset(pre, 0, sizeof(pre));
 66        memset(sccN, 0, sizeof(sccN));
 67        memset(vis, 0, sizeof(vis));
 68        memset(used, 0, sizeof(used));
 69        while(m--){
 70           int u, v;
 71           scanf("%d%d", &u, &v);
 72           edge[u].push_back(v);           
 73        }   
 74        for(int i=1; i<=n; ++i)
 75           if(!pre[i]) 
 76              dfs(i);
 77        int num=0;    
 78        sum=0;
 79        used[1]=1;
 80        for(int i=1; i<=n; ++i){
 81           
 82           if(sccN[i]==1)
 83              ++num;
 84           else if(!used[sccN[i]]){
 85              memset(vis, 0, sizeof(vis));
 86              xx=sccN[i];
 87              used[sccN[i]]=1; 
 88              dfs2(i);
 89           }
 90        }
 91        
 92        if(sum==(cnt+1)*cnt/2-1)//最后將能到達標號為1的連通分量的所有強連通分量的標號加起來 
 93           printf("%d\n", num);
 94        else printf("0\n");
 95        for(int i=1; i<=n; ++i)
 96           edge[i].clear();
 97        while(!s.empty())
 98           s.pop();
 99    }
100    return 0;    
101 }

?


?

?

轉載于:https://www.cnblogs.com/hujunzheng/p/3895221.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/531799.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/531799.shtml
英文地址,請注明出處:http://en.pswp.cn/news/531799.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

yum刪除mysql數據庫_MySQL數據庫之Centos中徹底刪除Mysql(rpm、yum安裝的情況)

本文主要向大家介紹了MySQL數據庫之Centos中徹底刪除Mysql(rpm、yum安裝的情況) &#xff0c;通過具體的內容向大家展現&#xff0c;希望對大家學習MySQL數據庫有所幫助。我用的centos6&#xff0c;mysql讓我整出了各種問題&#xff0c;我想重裝一個全新的mysql&#xff0c;yum…

計算機視覺領域常見期刊和會議,計算機視覺領域常見期刊和會議

會議&#xff1a;ICCV&#xff1a; IEEE International Conference on Computer Vision(每兩年舉辦一次&#xff0c;由IEEE主辦&#xff0c;百度百科&#xff1a;https://baike.baidu.com/item/iccv/7054436?fraladdin&#xff0c;ICCV 2017&#xff1a;http://iccv2017.thecv…

mysql怎么新增_mysql怎么新增用戶

匿名用戶1級2018-01-27 回答展開全部首先以root身份登錄到MySQL服務器中。$ mysql -u root -p當驗證提示出現的時候&#xff0c;輸入MySQL的root帳號的密碼。創建一個MySQL用戶使用如下命令創建一個用戶名和密碼分別為"myuser"和"mypassword"的用戶。mysql…

江西財經大學計算機排名2019,2019年全國商科院校評價報告出爐 江西財經大學排名第七...

中國江西網/江西頭條新聞客戶端訊 記者鄭周贇報道&#xff1a;6月5日&#xff0c;江西財經大學應用統計研究中心發布了2019年全國商科院校評價報告&#xff0c;江西財經大學在46所指標數據完整的商科院校中綜合得分排名第七。該報告權衡了指標的完備性和可獲得性&#xff0c;確…

Uvaoj10054 - The Necklace

1 /*2 題意&#xff1a;打印歐拉回路&#xff01;3 思路&#xff1a;開始時不明白&#xff0c;dfs為什么是后序遍歷&#xff1f; 4 因為歐拉回路本身是一條回路&#xff0c;那么我們在dfs時&#xff0c;可能存在提前找到回路&#xff0c;這條回路可能不是歐拉回路&…

w7計算機應用放大按鍵,Win7窗口最大化和最小化快捷鍵是什么

Win7窗口最大化和最小化快捷鍵是什么Win7有很多快捷鍵&#xff0c;你都知道多少呢&#xff1f;今天小編給大家科普的是win7窗口最大化和最小化快捷鍵&#xff0c;下面就一起來了解看看吧&#xff01;Windows 鍵 方向鍵“↑”使當前使用的窗口最大化。Windows 鍵 方向鍵“↓”…

s7-1200跟mysql_讓西門子S7-1200直接連接MySQL數據庫!!!

最近項目上有個需求&#xff0c;要把采集的數據存儲到數據庫中&#xff0c;當前西門子有很多方法&#xff0c;必讀IDB&#xff0c;還有通過WINCC的腳本&#xff0c;第三方的軟件等等&#xff0c;但是隨著發展&#xff0c;有些需求希望設備直接到數據庫&#xff0c;比如云端的RD…

uva oj 567 - Risk(Floyd算法)

1 /*2 一張有20個頂點的圖上。3 依次輸入每個點與哪些點直接相連。4 并且多次詢問兩點間&#xff0c;最短需要經過幾條路才能從一點到達另一點。5 6 bfs 水過7 */8 #include<iostream>9 #include<cstring> 10 #include<vector> 11 #include<cstdio> 12…

10034 - Freckles 克魯斯克爾最小生成樹!~

1 /*2 10034 - Freckles3 克魯斯克爾最小生成樹&#xff01;&#xff5e; 4 */5 #include<iostream>6 #include<cstdio>7 #include<cmath>8 #include<algorithm>9 using namespace std; 10 11 struct node{ 12 double x, y; 13 }; 14 15 struct t…

win7個人計算機的ip地址,win7計算機ip地址查詢_win7本機ip地址查詢

2016-12-09 11:40:21查找計算機的ip地址的方法&#xff1a;點擊你的電腦桌面左下角的“開始”找到“運行”點擊運行, 在出現的對話框里面輸入“cmd” 點擊確定然后就會出現一個黑色的命令行窗口,你會看到“&...2016-12-19 15:59:44手機設置靜態IP 1、點設置-線網絡 2、WLAN…

最全的mysql 5.7.13_最全的mysql 5.7.13 安裝配置方法圖文教程(linux) 強烈推薦!

linux環境Mysql 5.7.13安裝教程分享給大家&#xff0c;供大家參考&#xff0c;具體內容如下1系統約定安裝文件下載目錄&#xff1a;/data/softwareMysql目錄安裝位置&#xff1a;/usr/local/mysql數據庫保存位置&#xff1a;/data/mysql日志保存位置&#xff1a;/data/log/mysq…

iis 日志 post數據_云原生日志的趨勢(1):logscape和logiq

作為日志產品的PM&#xff0c;跟進國內外日志產品動向是個長期工作。這幾天翻新一些歷史記錄&#xff0c;發現logscape自2017年開源以來&#xff0c;突然2019年10月又更新了一會。于是順著翻翻logscape的github賬號&#xff0c;起了興致來寫點文字。https://github.com/logscap…

Uvaoj 10048 - Audiophobia(Floyd算法變形)

1 /*2 題目大意&#xff1a;3 從一個點到達另一個點有多條路徑&#xff0c;求這多條路經中最大噪音值的最小值&#xff01; 、4 5 思路&#xff1a;最多有100個點&#xff0c;然后又是多次查詢&#xff0c;想都不用想&#xff0c;Floyd算法走起&#xff01; 6 …

南通大學計算機系本二,2012年南通大學計算機科學與技術學院江蘇省內第二批本科(院校代碼:1301)...

第二批本科(院校代碼&#xff1a;1301)序號專 業 名 稱學制科類計劃數1漢語言文學(師范)四文科552漢語言文學(高級文秘)四文科803廣播電視新聞學四文科304對外漢語四文科285歷史學(師范)四文科306思想政治教育(師范)四文科207社會工作四文科258行政管理四文科459公共事業管理四…

大學計算機基礎總結,大學計算機基礎第二章總結

數&#xff1a;計算機的數據的基本形態是二進制數數制&#xff1a;可以直接進行數學計算數字碼制&#xff1a;用來表示不同對象屬性● 數制(計數體制)多位數中每一位的構成方法以及實現從低位到高位的進位規則(也叫做進制)▲ 常用數制&#xff1a;R進制有R個數碼&#xff0c;數…

UvaOJ10369 - Arctic Network

1 /*2 The first line of each test case contains 1 < S < 100, the number of satellite channels!3 注意&#xff1a;S表示一共有多少個衛星&#xff0c;那么就是有 最多有S-1個通道&#xff01; 然后將最小生成樹中的后邊的 S-1通道去掉就行了&#xff01; 4…

獲取list泛型_泛型

泛型什么是泛型&#xff1f;為什么使用泛型&#xff1f;泛型的出現意味著編寫的代碼可以被不同類型的對象所重用&#xff0c;提升了代碼的重用性。泛型的本質是參數化類型&#xff0c;即將所需操作的數據類型設置為一個參數。 舉個實際中的栗子&#xff1a;我們需要設計一個柜子…

w10計算機字體怎么設置在哪里設置,如何設置修改win10系統電腦的顯示字體

如何設置修改win10系統電腦的顯示字體騰訊視頻/愛奇藝/優酷/外賣 充值4折起今天給大家介紹一下如何設置修改win10系統電腦的顯示字體的具體操作步驟。1. 首先鼠標左鍵開始&#xff0c;然后在菜單下的左下角選擇設置圖標。2. 進入Windows 設置后&#xff0c;單擊個性化。3. 接著…

uva 10801 - Lift Hopping(最短路Dijkstra)

1 /*2 題目大意&#xff1a;3 就是一幢大廈中有0&#xff5e;99的樓層, 然后有1&#xff5e;5個電梯&#xff01;每個電梯有一定的上升或下降速度和樓層的停止的位置&#xff01;4 問從第0層樓到第k層最少經過多長時間到達&#xff01;5 6 思路&#x…

powerdesigner mysql 自增主鍵_PowerDesigner Mysql 主鍵自增、初始值、字符集

自增在你所要設為自增型的鍵上(比如你的id)雙擊&#xff0c;彈出一個Column Properties對話框&#xff0c;右下角有一個Identify的選擇框&#xff0c;選中它OK&#xff0c;就可以了。 再去查看Preview&#xff0c;就能看到AUTO_INCREMENT。起始值默認自增字段從1開始, 如果需要…