HDU 5695 Gym Class 拓扑排序
2016-05-22 10:49
441 查看
Gym Class
题目连接:
http://acm.hdu.edu.cn/showproblem.php?pid=5695Description
众所周知,度度熊喜欢各类体育活动。今天,它终于当上了梦寐以求的体育课老师。第一次课上,它发现一个有趣的事情。在上课之前,所有同学要排成一列, 假设最开始每个人有一个唯一的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
31 0
2 1
1 2
3 1
3 1
Sample Output
12
6
Hint
题意
题解:
在满足拓扑关系的条件下,每次贪心扔一个最大的上去就好了然后最后在统计一下答案就可以了
代码
#include<iostream> #include<queue> #include<math.h> #include<algorithm> #include<cstring> #include<stdio.h> using namespace std; const int maxn = 1e5+7; int n,m; int a[maxn],d[maxn]; vector<int> E[maxn]; priority_queue<int> Q; void init() { memset(a,0,sizeof(a)); memset(d,0,sizeof(d)); for(int i=0;i<maxn;i++)E[i].clear(); while(!Q.empty())Q.pop(); } void solve() { init(); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); E[x].push_back(y); d[y]++; } for(int i=1;i<=n;i++) { if(d[i]==0)Q.push(i); } int tot = 0; while(!Q.empty()) { int now = Q.top(); Q.pop(); a[tot++]=now; for(int i=0;i<E[now].size();i++) { d[E[now][i]]--; if(d[E[now][i]]==0) Q.push(E[now][i]); } } long long ans = 0; int tmp = 1e9; for(int i=0;i<n;i++) { tmp = min(tmp,a[i]); ans+=tmp; } cout<<ans<<endl; } int main() { int t;scanf("%d",&t); while(t--)solve(); return 0; }
相关文章推荐
- 字符串编码与项目编码问题
- 第十二周学习进度表
- 【LeetCode】55. Jump Game
- DHCP源码分析-dhcpv6模块
- 1020 孪生蜘蛛
- hdu 2438题解
- POJ 1012 Joseph
- 软件项目进度管理
- 面积(area)
- Django基础(三)
- LeetCode:Intersection of Two Arrays II
- StrBuffer 类的应用---暗文的解密
- android避免OOM的几种常见方式
- HDU 5694 BD String 迭代
- FCM压缩算法
- github命令大全
- centos6.5卸载自带mysql
- 《Zero to One》读书笔记
- NEFU 1160 线段树
- 封装ajax——前端工程师和派孔明