6081: Gym Class(拓扑排序+优先队列)
6081: Gym Class ![分享至QQ空间](http://www.tzcoder.cn/acmhome/forum/images/ico_qzone.gif)
时间限制(普通/Java):1000MS/3000MS 内存限制:65536KByte
总提交: 40 测试通过:10
View Code
总提交: 40 测试通过:10
描述
众所周知,度度熊喜欢各类体育活动。
今天,它终于当上了梦寐以求的体育课老师。第一次课上,它发现一个有趣的事情。在上课之前,所有同学要排成一列, 假设最开始每个人有一个唯一的ID,从1到N,在排好队之后,每个同学会找出包括自己在内的前方所有同学的最小ID,作为自己评价这堂课的分数。麻烦的是,有一些同学不希望某个(些)同学排在他(她)前面,在满足这个前提的情况下,新晋体育课老师——度度熊,希望最后的排队结果可以使得所有同学的评价分数和最大。
输入
第一行一个整数T,表示T(1≤T≤30) 组数据。
对于每组数据,第一行输入两个整数N和M(1≤N≤100000,0≤M≤100000),分别表示总人数和某些同学的偏好。
接下来M行,每行两个整数A 和B(1≤A,B≤N),表示ID为A的同学不希望ID为B的同学排在他(她)之前。你可以认为题目保证至少有一种排列方法是符合所有要求的。
输出
对于每组数据,输出最大分数 。
样例输入
样例输出
1
2
6
解题思路: 拓扑排序确定关系,大的数尽量在前面小的数尽量在后面即可! 而优先队列恰好有这种功能
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 5 int t,n,m; 6 const int maxn=1e5+5; 7 int in[maxn]; 8 vector<ll> vec; 9 vector<int> G[maxn]; 10 11 priority_queue<int> que; 12 void init(){ 13 for(int i=1;i<=n;i++) G[i].clear(); 14 vec.clear(); 15 memset(in,0,sizeof(in)); 16 while(!que.empty()) que.pop(); 17 } 18 19 void topsort(){ 20 for(int i=1;i<=n;i++){ 21 if(in[i]==0) que.push(i); 22 } 23 while(!que.empty()){ 24 int top=que.top(); que.pop(); 25 vec.push_back(top); 26 for(auto X:G[top]){ 27 if(in[X]){ 28 --in[X]; 29 if(in[X]==0){ 30 que.push(X); 31 } 32 } 33 } 34 } 35 36 } 37 38 int main(){ 39 ios::sync_with_stdio(false); 40 cin>>t; 41 while(t--){ 42 init(); 43 cin>>n>>m; 44 for(int i=1,d1,d2;i<=m;i++){ 45 cin>>d1>>d2; 46 G[d1].push_back(d2); 47 in[d2]++; 48 } 49 topsort(); 50 int len=vec.size(); 51 ll minn=0x3f3f3f3f3f3f3f3f,res=0; 52 for(int i=0;i<=len-1;i++){ 53 minn=min(minn,vec[i]); 54 // cout << minn << endl; 55 res+=minn; 56 } 57 cout << res << endl; 58 } 59 return 0; 60 61 62 }