大學班級選班長,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
解題思路:
targin縮點後 得到乙個dag(有向無環圖,順便記錄下每個強連通圖包含的節點數),每個強連通圖可以用乙個唯一編號去代替,這樣可以知道有多少個強連通圖是沒有出度的,我們的答案就在這些 沒有出度的強連通圖中。因為如果乙個強連通圖有出度,那麼它一定不是得票最多的。
縮點後,不難發現對於屬於第 i 個 scc 的點來說,答案分為 兩部分,令 scc[i] 表示第 i 個 scc 中點的個數
• 當前 scc 中的點,ans += scc[i] – 1(去除自己)
• 其它 scc 中的點 • sum ( scc[j] ),其中 j 可到達 i
• 稍加思考,可以發現最後答案一定出現在出度為 0 的 scc 中
#include
#include
#include
#include
#include
#include
using
namespace std;
typedef
long
long ll;
const
int inf =
1e8;
const
int maxn =
5010
;vector<
int> g1[maxn]
,g2[maxn]
;int low[maxn]
,dfn[maxn]
,in[maxn]
;int vis[maxn]
,instack[maxn]
,scc[maxn]
,ans[maxn]
,sccsum[maxn]
;int n,tot,num,sum;
stack<
int> s;
void
init()
memset
(low,0,
sizeof
(low));
memset
(dfn,0,
sizeof
(dfn));
memset
(in,0,
sizeof
(in));
memset
(ans,0,
sizeof
(ans));
memset
(vis,0,
sizeof
(vis));
memset
(instack,0,
sizeof
(instack));
memset
(scc,0,
sizeof
(scc));
memset
(sccsum,-1
,sizeof
(sccsum));
while
(s.size()
) s.
pop();
}void
tarjan
(int x)
else
if(instack[v])}
if(low[x]
== dfn[x]
) ans[num]
= cnt;
num++;}
}void
dfs(
int x)
}int
main()
for(
int i=
0;ifor(
int i=
0;i}int res =-1
;for
(int i=
0;i}printf
("case %d: %d\n"
,count++
,res-1)
;bool flag=
true
;for
(int i=
0;iprintf
("\n");
}return0;
}
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 本題有多...
week8作業C 班長競選 kosaraju
題目 大學班級選班長,n 個同學均可以發表意見 若意見為 a b 則表示 a 認為 b 合適,意見具有傳遞性,即 a 認為 b 合適,b 認為 c 合適,則 a 也認為 c 合適 勤勞的 tt 收集了m條意見,想要知道最高票數,並給出乙份候選人名單,即所有得票最多的同學,你能幫幫他嗎?輸入 本題有多...