拓扑排序 HDU - 5695
今天,它终于当上了梦寐以求的体育课老师。第一次课上,它发现一个有趣的事情。在上课之前,所有同学要排成一列, 假设最开始每个人有一个唯一的ID,从1到NN,在排好队之后,每个同学会找出包括自己在内的前方所有同学的最小ID,作为自己评价这堂课的分数。麻烦的是,有一些同学不希望某个(些)同学排在他(她)前面,在满足这个前提的情况下,新晋体育课老师——度度熊,希望最后的排队结果可以使得所有同学的评价分数和最大。
Input第一行一个整数TT,表示T(1≤T≤30)T(1≤T≤30) 组数据。
对于每组数据,第一行输入两个整数NN和M(1≤N≤100000,0≤M≤100000)M(1≤N≤100000,0≤M≤100000),分别表示总人数和某些同学的偏好。
接下来MM行,每行两个整数AA 和B(1≤A,B≤N)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 <iostream> #include <string> #include <cstdio> #include <queue> #include <vector> #include <algorithm> #include <cstring> using namespace std; const int maxn = 100010; const int inf = 0x3f3f3f3f3f; vector<int> G[maxn];//由于直接用int G[maxn][maxn] 会占用大内存,有可能会爆 int indegree[maxn];//这是对点的入度标记 int main() { int T; scanf("%d",&T); int n,m; while(T--) { scanf("%d%d",&n,&m); memset(indegree,0,sizeof(indegree));//清空处理,同下 memset(G,0,sizeof(G));//第二阶段代码会对这一点进行优化; int u,v; for(int i=0;i<m;i++) { scanf("%d%d",&u,&v); G[u].push_back(v);//和点u,存在偏序关系的点 v,压入 indegree[v]++;//哈希图特点,偏序关系,由u->v,点v的入度++,不需要考虑出度 }//具体可以参考另一篇博文 priority_queue<int> que;//优先队列对压入的点进行维护 //优先队列默认是大的在前,也就是降序 for(int k=1;k<=n;k++) if(!indegree[k]) que.push(k);//先将没有入度的点压入, //没有入度的点,也就是不存在以该点为终点的偏序关系,对整体排序没有影响 //在哈希图上体现就是(假设哈希图由下往上绘制),这个点是悬挂点,极小点(离散数学) long long res=0;//long long 保险,看题目吧 int u_num=inf;//考虑程序的鲁棒性,定义为无限大 while(!que.empty())//队列的维护+模拟过程 { int num=que.top();//头,是不是有点像bfs,这就对了 que.pop();//就按照bfs代码方式搞下去,部分改变 u_num=min(u_num,num); res+=u_num; for(int i=0;i<G[num].size();i++) { int v=G[num][i];//这是对该点排序后,删除所有把该点作为起点的线段 //也可以理解为,除去哈希图上的这个点->哈希图不允许悬挂边的存在 indegree[v]--;//对应的终点入度-- if(!indegree[v])//入度为0,对后续排序没影响,选择压入 que.push(v); } } printf("%lld\n",res);//输出总花费 } }
运行702ms;
其实可以看出来memset遍历清空费的时间是比较大的,可以根据vector特点修改下(借鉴了求前辈的博文)
#include <iostream> #include <string> #include <cstdio> #include <queue> #include <vector> #include <algorithm> #include <cstring> using namespace std; const int maxn = 100010; const int inf = 0x3f3f3f3f3f; vector<int> G[maxn]; int indegree[maxn]; int main() { int T; scanf("%d",&T); int n,m; while(T--) { scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) { indegree[i] = 0; G[i].clear(); } int u,v; for(int i=1;i<=m;i++) { scanf("%d%d",&u,&v); G[u].push_back(v); indegree[v]++; } priority_queue<int> que; for(int k=1;k<=n;k++) if(!indegree[k]) que.push(k); long long res=0; int u_num=inf; while(!que.empty()) { int num=que.top(); que.pop(); u_num=min(u_num,num); res+=u_num; for(int i=0;i<G[num].size();i++) { int v=G[num][i]; indegree[v]--; if(!indegree[v]) que.push(v); } } printf("%lld\n",res); } }
608ms;确实,有点效果;
#include <iostream> #include <string> #include <cstdio> #include <queue> #include <vector> #include <algorithm> #include <cstring> using namespace std; const int maxn = 100010; const int inf = 0x3f3f3f3f3f; vector<int> G[maxn]; int indegree[maxn]; priority_queue<int> que; void combine(int a,int b) { G[a].push_back(b); indegree[b]++; return; } void del_gre(int num) { for(int i=0;i<G[num].size();i++) { int v=G[num][i]; indegree[v]--; if(!indegree[v]) que.push(v); } return; } int main() { int T; scanf("%d",&T); int n,m; while(T--) { while(!que.empty()) que.pop(); scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) { indegree[i] = 0; G[i].clear(); } int u,v; for(int i=1;i<=m;i++) { scanf("%d%d",&u,&v); combine(u,v); } for(int k=1;k<=n;k++) if(!indegree[k]) que.push(k); long long res=0; int u_num=inf; while(!que.empty()) { int num=que.top(); que.pop(); u_num=min(u_num,num); res+=u_num; del_gre(num); } printf("%lld\n",res); } }
根据我上个关于拓扑理解写的
670ms;
最后来一句,求关注~’
拓扑排序 HDU - 5695的更多相关文章
- 拓扑排序 - hdu 1285(普通和优先队列优化)
2017-09-12 19:50:58 writer:pprp 最近刚开始接触拓扑排序,拓扑排序适用于:无圈图的顶点的一种排序, 用来解决有优先级别的排序问题,比如课程先修后修,排名等. 主要实现:用 ...
- 拓扑排序 --- hdu 4948 : Kingdom
Kingdom Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- HDU - 5695 Gym Class 【拓扑排序】
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5695 思路 给定一些关系 进行拓扑排序 但是有一个要求 对于哪些没有确切的位置的点 要按照ID大小 I ...
- HDU 5695 ——Gym Class——————【贪心思想,拓扑排序】
Gym Class Time Limit: 6000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- 2016"百度之星" - 初赛(Astar Round2A)HDU 5695 拓扑排序+优先队列
Gym Class Time Limit: 6000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- HDU - 5695 Gym Class (优先队列+拓扑排序)
题意:有N个人,每个人的ID为1~N,部分同学A不希望部分同学B排在他之前,排好队之后,每个同学会找出包括自己在内的前方所有同学的最小ID,作为自己评价这堂课的分数.在满足这个前提的情况下,将N个人排 ...
- HDU 4857 逃生 (反向拓扑排序 & 容器实现)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 逃生 Time Limit: 2000/1000 MS (Java/Others) Mem ...
- ACM: HDU 1285 确定比赛名次 - 拓扑排序
HDU 1285 确定比赛名次 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u De ...
- ACM: hdu 2647 Reward -拓扑排序
hdu 2647 Reward Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Des ...
随机推荐
- 教育,创新,提升:Indiegogo和Kickstarter上受中国用户支持的10个众筹项目
中国的经济正在迅速发展,已成为世界第二大经济体.中国家庭随着经济水平的提高,越来越多父母愿意将自己的子女送到海外留学. 家长们希望自己的子女可以有机会接受国外大学优质的教育, 以便他们将来可以学成归来 ...
- 用mp3stego来加密与解密文件的几次尝试
用法来自实验吧的"Canon"隐写题目的灵感. 先来简单的聊一下这道题目,打开题目后发现了一个mp3文件,除此之外还有一枚压缩包.然而压缩包是加密的,看来我们需要通过解出来mp3里 ...
- Python操作csv文件
1.什么是csv文件 The so-called CSV (Comma Separated Values) format is the most common import and export fo ...
- vue + ajax + php 接口的使用小接
vue + ajax + php 接口的使用小接 前端代码: (获取用户信息,并渲染页面) userinfor.html <!DOCTYPE html> <html lang=&qu ...
- Mybatis了解(配置)
Mybatis是一个基于jdbc映射框架.它跟hibernate一样都是对数据库进行操作的.Mybatis 它是通过配置xml或者是注解来进行映射的配置,最后实现操作接口与pojo来操作数据库. 因此 ...
- Javascript从“繁”到“简”进行数组去重
随着JavaScript提供语法的增多,数组去重方式也越来越多.现在从最原始的方式到最简洁的方式,一步步进行剖析. 双重循环 数组去重,不就是比较数组元素,去掉重复出现的么.最原始的方式不正是双重循环 ...
- yum fastermirror插件屏蔽一些国内源
最近被yum上hust源的问题恶心的受不了了,真不明白这种源还活着有什么意义,干脆关了得了,省得恶心人,经常Errno 14,404not found,去网页一看,好家伙,提示404的xml.gz路径 ...
- typeof、constructor和instance
在JavaScript中,我们经常使用typeof来判断一个变量的类型,使用格式为:typeof(data)或typeof data.typeof返回的数据类型有六种:number.string.bo ...
- LeetCode 661. Image Smoother (图像平滑器)
Given a 2D integer matrix M representing the gray scale of an image, you need to design a smoother t ...
- spacemacs 初始安装报错
尝试使用emcas的配置文件spacemacs,第一次安装启动时,界面为纯白色,而且在输入完几个配置选项后,报了一个错误 Symbol's value as variable is void 根据官网 ...