程式設計思維 week8 作業C 班長競選

2021-10-05 03:45:19 字數 2140 閱讀 3043

大學班級選班長,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 本題有多...