題目要求
大學班級選班長,n 個同學均可以發表意見 若意見為 a b 則表示 a 認為 b 合適,意見具有傳遞性,即 a 認為 b 合適,b 認為 c 合適,則 a 也認為 c 合適 勤勞的 tt 收集了m條意見,想要知道最高票數,並給出乙份候選人名單,即所有得票最多的同學,你能幫幫他嗎?
input
本題有多組資料。第一行 t 表示資料組數。每組資料開始有兩個整數 n 和 m (2 <= n <= 5000, 0 3 3
1 02 1
0 2sample output
case 1: 2
0 1case 2: 2
0 1 2
求解思路
kosaraju求scc
a認為b合適,則a->b,求scc的過程為:
兩次dfs,第一次dfs確定原圖的逆後序序列,第二次dfs在反圖中按照逆後序序列進行遍歷,每次由起點遍歷到的點即構成乙個scc
2、縮點
記錄scc相互之間能否到達,視為有向邊,為降低複雜度,在尋找scc的過程中記錄能到達的scc,因為scnt為各個scc的計數,所以當scnt改變時則找到另乙個scc,此時將可到達的scc記錄在son中,son使用set避免重複。
3、找到出度為0的scc
最大值一定為出度為0的scc,所以遍歷son,當出度為0時,從該scc中的任乙個點出發,對反圖進行dfs,記錄能到達的點,即為該scc中所有點的得票數。將結果以pairtemp;//first為scc編號,second為數量 temp.first = k; temp.second = sum - 1;
的形式記錄在vector > ans;
中,同時,記錄最大得票數。
4. 輸出
遍歷scc,將ans中scc得票數為最大值得scc中所有點記錄在record陣列中,然後進行sort排序,公升序輸出得票最多的同學序號,複雜度為o(n^2)
**
#include
#include
#include
#define inf -1e8
#include
#include
#include
#include
using
namespace std;
#define n 5005
int c[n]
, dfn[n]
, vis[n]
, dcnt, scnt;
//dcnt-dfs序計數,scnt-scc計數
//dfn[i]-dfs後序列中第i個點
//c[i]-i 號點所在scc編號
vector<
int> g1[n]
, g2[n]
;//g1-原圖,g2-反圖
int viscon[n]
;set<
int> con[n]
;set<
int> son[n]
;//縮點後可到達的連通分量
int t, n, m;
vector
int,
int>> ans;
void
dfs1
(int x)
void
dfs2
(int x)}}
int sum =0;
void
dfs3
(int x)
}void
kosaraju()
//第二遍dfs
for(
int i = n-
1; i >=
0; i--
)++scnt;
dfs2
(dfn[i]);
}}}int
main()
ans.
clear()
;scanf
("%d%d"
,&n,
&m);
for(
int j =
0; j < m; j++
)kosaraju()
;//縮點
/* for (int k = 0; k < n; k++)
}} */
//找到出度為0的點,計算能到達的點
//找最大值
int themax =0;
for(
int k =
1; k <= scnt; k++
) sum =0;
memset
(viscon,0,
sizeof viscon)
;dfs3
(j);
pair<
int,
int> temp;
//first為scc編號,second為數量
temp.first = k; temp.second = sum -1;
ans.
push_back
(temp)
;//出度為0的點所在的scc記錄在ans中
// cout << temp.second << endl;
if(themax < sum -1)
}}//找最大值
/* int themax = 0;
for (int k = 0; k < ans.size(); k++)}*/
//輸出
int record[n]
;int current =0;
cout <<
"case "
<< i <<
": "
<< themax << endl;
for(
int k =
0; k < ans.
size()
; k++)}
}}sort
(record, record + current)
;for
(int k =
0; k < current; k++
)else}}
}
強連通分量SCC
poj2762 題意 給出n個點,對於每個點,如果任意選擇兩點s,e,都滿足s可以到達e或者e可以到達s,則輸出yes,否則輸出no。用了白書裡的模板 參考解決思路是 首先求出原圖g的強連通分量並且縮點,求出縮點後的圖mat,並且求出縮點後所有頂點的入度in。這時我們思考下,如果原圖g要是半連通的,...
SCC(強連通分量)
1.定義 在有向圖g中,如果兩個頂點間至少存在一條路徑,稱兩個頂點強連通 sc strongly connected 有向圖中的極大強連通子圖,成為強連通分量 scc strongly connected components 下圖中,子圖為乙個強連通分量,因為頂點1,2,3,4兩兩可達,也分別是兩...
強連通分量 Kosaraju
芝士 有向圖強連通分量在有向圖g中,如果兩個頂點vi,vj間 vi vj 有一條從vi到vj的有向路徑,同時還有一條從vj到vi的有向路徑,則稱兩個頂點強連通 strongly connected 如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。有向圖的極大強連通子圖,稱為強連通分量。如圖中1...