图论_拓扑排序_练习1(优先队列小顶堆)
Posted 山本夏木
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图论_拓扑排序_练习1(优先队列小顶堆)相关的知识,希望对你有一定的参考价值。
priority_queue
基本操作:
empty() 如果队列为空,则返回真
pop() 删除对顶元素,删除第一个元素
push() 加入一个元素
size() 返回优先队列中拥有的元素个数
top() 返回优先队列队顶元素,返回优先队列中有最高优先级的元素( #队列中为front() )
back() 返回优先队列队尾元素,返回优先队列中有最低优先级的元素
在默认的优先队列中,优先级高的先出队。在默认的int型中先出队的为较大的数。
priority_queue<vector<int>, less<int> > pq1; // 使用递增less<int>函数对象排序
priority_queue<deque<int>, greater<int> > pq2; // 使用递减greater<int>函数对象排序
声明方式:1、普通方法 2、自定义优先级 3、结构体声明方式
头文件:#include<queue> #include<functional>
参考博客:C++STL——优先队列
九度OJ-1449:确定比赛名次
- 题目描述:有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。
- 输入:输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。
- 输出:给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。
- 其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
- 这道题是拓扑排序的第一种应用:利用拓扑排序确定拓扑序列。
解法一:常规方法(每次从入度为0的结点中选取最小值)
#include<iostream> #include<stdio.h> #include<vector> #include<queue> using namespace std; vector<int> edge[501]; int main(){ int n,m; int inDegree[501]; bool flag[501]; while(scanf("%d%d",&n,&m)!=EOF){ vector<int> res; for(int i=1;i<=n;i++){ inDegree[i]=0; edge[i].clear(); flag[i]=false; } while(m--){ int a,b; scanf("%d%d",&a,&b); inDegree[b]++; edge[a].push_back(b); } int cnt=0; while(cnt!=n){ for(int i=1;i<=n;i++){ if(flag[i]) continue; if(inDegree[i]==0){ res.push_back(i); flag[i]=true; cnt++; for(int j=0;j<edge[i].size();j++) inDegree[edge[i][j]]--; break; } } } for(int i=0;i<n-1;i++) cout<<res[i]<<" "; cout<<res[n-1]<<endl; } return 0; }
解法二:优先队列小顶堆
#include<stdio.h> #include<iostream> #include<vector> #include<queue> #include<functional> using namespace std; priority_queue<int,vector<int>,greater<int> >Q; vector<int> edge[501]; int main(){ int n,m; int inDegree[501]; while(scanf("%d%d",&n,&m)!=EOF){ for(int i=1;i<=n;i++){ inDegree[i]=0; edge[i].clear(); } while(!Q.empty()) Q.pop(); while(m--){ int a,b; scanf("%d%d",&a,&b); edge[a].push_back(b); inDegree[b]++; } for(int i=1;i<=n;i++) if(inDegree[i]==0) Q.push(i); vector<int> res; while(!Q.empty()){ int top=Q.top(); Q.pop(); res.push_back(top); for(int i=0;i<edge[top].size();i++){ inDegree[edge[top][i]]--; if(inDegree[edge[top][i]]==0) Q.push(edge[top][i]); } } for(int i=0;i<n-1;i++) cout<<res[i]<<" "; cout<<res[n-1]<<endl; } return 0; }
以上是关于图论_拓扑排序_练习1(优先队列小顶堆)的主要内容,如果未能解决你的问题,请参考以下文章