Gym Class HDU - 5695

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

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

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

接下來MM行,每行兩個整數AA 和B(1A,BN)B(1≤A,B≤N),表示ID爲AA的同學不希望ID爲BB的同學排在他(她)之前。你可以認爲題目保證至少有一種排列方法是符合所有要求的。 
Output對於每組數據,輸出最大分數 。 Sample Input
3
1 0
2 1
1 2
3 1
3 1
Sample Output
1
2
6

拓撲排序,一個簡單的模版題,可以看一下我的上一篇博客借鑑的兩位大神的博客.

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<set>
#include<vector>
using namespace std;
priority_queue<int> out;
vector<int> op[100001];
int ru[100001];
int main()
{
    int T;
    scanf("%d", &T);
    int n,m;
    while(T--)
    {
       scanf("%d %d",&n,&m);

       for(int i=1; i<=n; i++)
       {
           op[i].clear();
       }
       memset(ru, 0,sizeof(ru));
       while(!out.empty()) out.pop();
       for(int i=1; i<=m; i++)
       {
           int u,v;
           scanf("%d %d",&u,&v);
           ru[v]++;
           op[u].push_back(v);
       }
       for(int i=1; i<=n; i++)
       {
           if(ru[i]==0)out.push(i);
       }
       //int edg = m;
       long long sum = 0;
       long long minn = 99999999999;
       while(!out.empty())
       {
           int p = out.top(); out.pop();
           minn = min(minn, (long long)p); sum += minn;
           int len = op[p].size();
           for(int i=0; i<len; i++)
           {
               ru[op[p][i]]--;
               if(ru[ op[p][i] ]==0){out.push(op[p][i]);}
           }
       }
       cout << sum << endl;
    }
    return 0;
}



水波.




發佈了85 篇原創文章 · 獲贊 5 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章