6082: 逃生 逆拓扑排序+优先队列
描述
糟糕的事情发生啦,现在大家都忙着逃命。但是逃命的通道很窄,大家只能排成一行。
现在有n个人,从1标号到n。同时有一些奇怪的约束条件,每个都形如:a必须在b之前。
同时,社会是不平等的,这些人有的穷有的富。1号最富,2号第二富,以此类推。有钱人就贿赂负责人,所以他们有一些好处。
负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,如果此时还有多种情况,就再让2号尽量靠前,如果还有多种情况,就让3号尽量靠前,以此类推。
那么你就要安排大家的顺序。我们保证一定有解。
输入
第一行一个整数T(1 <= T <= 5),表示测试数据的个数。
然后对于每个测试数据,第一行有两个整数n(1 <= n <= 30000)和m(1 <= m <= 100000),分别表示人数和约束的个数。
然后m行,每行两个整数a和b,表示有一个约束a号必须在b号之前。a和b必然不同。
输出
对每个测试数据,输出一行排队的顺序,用空格隔开。
样例输入
1
5 10
3 5
1 4
2 5
1 2
3 4
1 4
2 3
1 5
3 5
1 2
样例输出
1 2 3 4 5
采用逆向拓扑排序从后往前推,并用优先队列优先选取较小的点
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N = 3e4+10,inf = 0x3f3f3f3f; int gcd(int a,int b){return a==0?b:gcd(b%a,a);} int n,m,t; vector<int>g[N]; int cd[N]; void topsort() { priority_queue<int> q; stack<int>s; for(int i=1;i<=n;i++) if(cd[i]==0)q.push(i),cd[i] = -1; while(!q.empty()) { int x = q.top();q.pop();s.push(x); for(int i=0;i<g[x].size();i++) { cd[g[x][i]]--; if(cd[g[x][i]]==0)q.push(g[x][i]); } } cout<<s.top();s.pop(); while(!s.empty()) { cout<<" "<<s.top();s.pop(); } cout<<endl; } int main() { cin>>t; while(t--) { cin>>n>>m; memset(cd,0,sizeof(cd)); for(int i=1;i<=n;i++)g[i].clear(); for(int i=1;i<=m;i++) { int x,y; cin>>x>>y; g[y].push_back(x); cd[x]++; } topsort(); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现