大學班級選班長,n 個同學均可以發表意見 若意見為 a b 則表示 a 認為 b 合適,意見具有傳遞性,即 a 認為 b 合適,b 認為 c 合適,則 a 也認為 c 合適 勤勞的 tt 收集了m條意見,想要知道最高票數,並給出乙份候選人名單,即所有得票最多的同學,你能幫幫他嗎?
本題有多組資料。第一行 t 表示資料組數。每組資料開始有兩個整數 n 和 m (2 <= n <= 5000, 0 對於每組資料,第一行輸出 「case x: 」,x 表示資料的編號,從1開始,緊跟著是最高的票數。 接下來一行輸出得票最多的同學的編號,用空格隔開,不忽略行末空格!
2
4 33 2
2 02 1
3 31 0
2 10 2
case 1: 2
0 1case 2: 2
0 1 2
a認為b合適可以看作點a指向點b的有向邊,則題目可以化為有向圖,使用kosaraju求出 scc 並縮點,將原來的圖化為scc的有向圖。
發現答案一定出現在出度為0的scc中。那麼答案=該scc中包含的成員數+可達該scc的scc的成員數。
將邊反向,對每個入度為 0 的點進行 dfs,計算其能到達的點的sum(scc[j]),即可得到答案。
注意,同學的編號從0開始,而scc的編號從1開始。
#include
#include
#include
#include
#include
using
namespace std;
bool vis[
5005];
int n,m,c[
5005
],dfn[
5005
],dcnt,scnt,indegree[
5005];
vector<
int> g1[
5005
],g2[
5005
],g3[
5005];
int cnt[
5005
],ans[
5005
],scc[
5005];
void
dfs1
(int x)
dfn[
++dcnt]
=x;}
void
dfs2
(int x)
}void
kosaraju()
}}void
init()
}void
dfs3
(int x)
intmain()
kosaraju()
;for
(int j=
0;j)for
(int k=
0;k.size()
;k++)if
(c[j]
!=c[g1[j]
[k]]
)//兩點不在同一連通圖
g3[c[g1[j]
[k]]].
push_back
(c[j]);
//存反圖
for(
int j=
1;j<=n;j++
)for
(int j=
0;j)//每個scc的點的個數
cnt[c[j]]++
;for
(int j=
1;j<=scnt;j++)}
int max=0;
for(
int j=
1;j<=scnt;j++)}
int tot=0;
for(
int j=
1;j<=scnt;j++)}
printf
("case %d: %d\n"
,i,max)
;bool flag=
false
;for
(int j=
0;j)else
printf
(" %d"
,j);}}
printf
("\n");
}return0;
}
set去重確實好用。
題目鏈結
SDU程式設計思維Week8 作業 C 班長競選
大學班級選班長,n 個同學均可以發表意見 若意見為 a b 則表示 a 認為 b 合適,意見具有傳遞性,即 a 認為 b 合適,b 認為 c 合適,則 a 也認為 c 合適。勤勞的 tt 收集了m條意見,想要知道最高票數,並給出乙份候選人名單,即所有得票最多的同學 本題有多組資料。第一行 t 表示資...
Week8作業 C 班長競選
問題描述 大學班級選班長,n個同學均可以發表意見。若意見為a b,則表示a認為b合適。意見具有傳遞性,即a認為b合適,b認為c合適,則a也認為c合適。共m條意見,要求出最高票數和候選人名單。準備知識 kosaraju演算法 1.第一遍 dfs 確定原圖的逆後序序列。2.第二遍 dfs 在反圖中按照逆...
C 班長競選(Week 8作業)
大學班級選班長,n 個同學均可以發表意見 若意見為 a b 則表示 a 認為 b 合適,意見具有傳遞性,即 a 認為 b 合適,b 認為 c 合適,則 a 也認為 c 合適 勤勞的 tt 收集了m條意見,想要知道最高票數,並給出乙份候選人名單,即所有得票最多的同學,你能幫幫他嗎?input 本題有多...