大學班級選班長,n 個同學均可以發表意見 若意見為 a b 則表示 a 認為 b 合適,意見具有傳遞性,即 a 認為 b 合適,b 認為 c 合適,則 a 也認為 c 合適 勤勞的 tt 收集了m條意見,想要知道最高票數,並給出乙份候選人名單,即所有得票最多的同學,你能幫幫他嗎?
本題有多組資料。第一行 t 表示資料組數。每組資料開始有兩個整數 n 和 m (2 <= n <= 5000, 0 對於每組資料,第一行輸出 「case x: 」,x 表示資料的編號,從1開始,緊跟著是最高的票數。 接下來一行輸出得票最多的同學的編號,用空格隔開,不忽略行末空格!
轉化成圖論問題
求乙個人的票數可以轉化為有多少點可以到達該點,因為該圖可能存在環,所以不能用拓撲,因此,可以用kosaraju求出強連通分量scc,進行縮點,然後變成乙個無環的圖
縮點後,則對於屬於第 i 個 scc 的點來說,答案分為
兩部分,令 scc[i] 表示第 i 個 scc 中點的個數
• 當前 scc 中的點,ans += scc[i] – 1(去除自己)
• 其它 scc 中的點
• sum ( scc[ j] ),其中 j 可到達 i
還有用反證法可以發現最後答案一定出現在出度為 0 的 scc,
因此 在反圖中可以用dfs求出可以到達的點
kosaraju
//求強連通scc//在有向圖中只有scc中兩兩互達
第一遍dfs確定原圖的逆後序序列
第二遍dfs 在反圖中按照逆後序序列進行遍歷
每次由起點遍歷到的點即構成乙個scc
縮點後將變成乙個無環圖比較好處理
#include
#include
#include
#include
using
namespace std;
int dcnt,scnt,count,n,m;
vector<
int>ve[
5010
],ve1[
5010
],su[
5010];
int scc[
5010
],dfn[
5010
],c[
5010
],degree[
5010
],ans[
5010];
bool vis[
5010];
void
dfs1
(int x)
dfn[dcnt++
]=x;
//後序序列
}void
dfs2
(int x)
//反圖
}void
dfs3
(int x)
void
kosaraju()
//有的題目中可以考慮反圖的作用
//c[i]表示i所在的scc編號
intmain()
kosaraju()
;//求強連通
for(
int i=
0;i)//縮點
}for
(int i=
1;i<=scnt;i++
)//記錄入度
for(
int j=
0;j.size()
;j++
) degree[su[i]
[j]]++;
memset
(ans,0,
sizeof
(ans));
int mmax=0;
for(
int i=
1;i<=scnt;i++
)//用ans來記錄每個點可以到達的點數 if(
!degree[i]
)//入度為0的點
} cout<<
"case"
<<
' '<": "
;cout
for(
int i=
0;i)} cout
}
班長競選 Kosaraju演算法
題意 大學班級選班長,n 個同學均可以發表意見 若意見為 a b 則表示 a 認為 b 合適,意見具有傳遞性,即 a 認為 b 合適,b 認為 c 合適,則 a 也認為 c 合適 勤勞的 tt 收集了m條意見,想要知道最高票數,並給出乙份候選人名單,即所有得票最多的同學,你能幫幫他嗎?input 本...
Kosaraju模板題 班長競選
大學班級選班長,n 個同學均可以發表意見 若意見為 a b 則表示 a 認為 b 合適,意見具有傳遞性,即 a 認為 b 合適,b 認為 c 合適,則 a 也認為 c 合適 勤勞的 tt 收集了m條意見,想要知道最高票數,並給出乙份候選人名單,即所有得票最多的同學,你能幫幫他嗎?輸入 本題有多組資料...
班長競選(kosaraju縮點
大學班級選班長,n 個同學均可以發表意見 若意見為 a b 則表示 a 認為 b 合適,意見具有傳遞性,即 a 認為 b 合適,b 認為 c 合適,則 a 也認為 c 合適 勤勞的 tt 收集了m條意見,想要知道最高票數,並給出乙份候選人名單,即所有得票最多的同學,你能幫幫他嗎?本題有多組資料。第一...