1. 程式人生 > >hdu 5695 Gym Class (拓撲排序)

hdu 5695 Gym Class (拓撲排序)

font gym 輸入 整數 div 情況 -- bit const

Description

眾所周知,度度熊喜歡各類體育活動。

今天,它終於當上了夢寐以求的體育課老師。第一次課上,它發現一個有趣的事情。在上課之前,所有同學要排成一列, 假設最開始每個人有一個唯一的ID,從1到N,在排好隊之後,每個同學會找出包括自己在內的前方所有同學的最小ID,作為自己評價這堂課的分數。麻煩的是,有一些同學不希望某個(些)同學排在他(她)前面,在滿足這個前提的情況下,新晉體育課老師——度度熊,希望最後的排隊結果可以使得所有同學的評價分數和最大。

Input

第一行一個整數T,表示T(1≤T≤30) 組數據。

對於每組數據,第一行輸入兩個整數N和M(1≤N≤100000,0≤M≤100000),分別表示總人數和某些同學的偏好。

接下來M行,每行兩個整數A 和B(1≤A,B≤N),表示ID為A的同學不希望ID為B的同學排在他(她)之前。你可以認為題目保證至少有一種排列方法是符合所有要求的。

Output

對於每組數據,輸出最大分數 。

Sample Input

3
1 0
2 1
1 2
3 1
3 1

Sample Output

1
2
6

思路:我們對於這個進行一下拓撲排序,然後貪心的每次加入一個最大的

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 #define inf 0x3f3f3f3f
 5 const int maxn = 110000;
 6
int n,m; 7 int stk[maxn],in[maxn];//stk裏面存拓撲排序,in表示入度 8 vector<int> e[maxn]; 9 priority_queue <int> q; 10 void init () 11 { 12 memset(stk,0,sizeof stk); 13 memset(in,0,sizeof in); 14 for (int i=0;i<maxn;++i) 15 e[i].clear(); 16 while (!q.empty()) q.pop(); 17 } 18
int main() 19 { 20 //freopen("de.txt","r",stdin); 21 int T; 22 scanf("%d",&T); 23 while (T--){ 24 scanf("%d%d",&n,&m); 25 init(); 26 for (int i=0;i<m;++i){ 27 int x,y; 28 scanf("%d%d",&x,&y); 29 e[x].push_back(y); 30 in[y]++; 31 } 32 for (int i=1;i<=n;++i) 33 if (in[i]==0) q.push(i); 34 int tot = 0; 35 while (!q.empty()){ 36 int now = q.top(); 37 q.pop(); 38 stk[tot++]=now; 39 for (int i=0;i<e[now].size();++i){ 40 int nxt = e[now][i]; 41 in[nxt]--; 42 if (in[nxt]==0) 43 q.push(nxt); 44 } 45 } 46 long long ans = 0; 47 int tmp = inf; 48 for (int i=0;i<n;++i){ 49 tmp = min(tmp,stk[i]); 50 ans+=tmp; 51 } 52 printf("%lld\n",ans); 53 } 54 return 0; 55 }

hdu 5695 Gym Class (拓撲排序)