博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
逃生_拓扑排序
阅读量:5054 次
发布时间:2019-06-12

本文共 1941 字,大约阅读时间需要 6 分钟。

题目质量非常好  题意很简单,用的知识点也很简单   拓扑排序+ 优先队列

也可以在杭电上提交

bestcoder round1 逃生

 

一个朴素的想法: 正常建图 , 先把入度为0的点加入优先队列,小的在前,直接拓扑排序

BUT    WA 

WA的毫无情谊

为什么呢?    参考这位大佬的博客  http://blog.csdn.net/Lawliet1993/article/details/51043070

来个例子 

存在拓扑关系: 

5 -> 3 -> 1 
6 -> 4 -> 2 
直接拓扑排序的结果是 5 3 1 6 4 2,结果是正确的(1号尽可能的在前面了) ,看起来好像直接拓扑排序就可以了,但是为什么提交后却wa了呢,别急,我们再看一个例子: 
6 -> 3 -> 1 
5 -> 4 -> 2 
直接拓扑排序的结果是:5 4 2 6 3 1 ,结果是错误的,因为我们可以把1号安排到更前面的位置 即:6 3 1 5 4 2(正确答案)。 

 

大佬的思路: 正向的处理不方便,反向建图!  反向建图对拓扑序有什么影响呢?

  正向建图的最后一个点在反向建图中会在第一个!也就是说 拓扑序会相反!  得到的拓扑序反向就是答案

根据题目要求   序号大的点应该尽量排在后面  使用优先队列,大的点排在前面 ,拓扑排序

大佬代码

#include 
using namespace std;const int maxn = 31000;pair
a[maxn * 4];int h[maxn];int in[maxn];int ans[maxn],cnt;int main(){ int tt; scanf("%d",&tt); int x,y; while(tt--) { int n,m; memset(h,0,sizeof(h)); memset(in,0,sizeof(in)); scanf("%d%d",&n,&m); cnt = 0; for(int i=1;i<=m;i++) { scanf("%d%d",&y,&x); if(h[x] == 0){ h[x] = i; a[i].first = y; a[i].second = 0; in[y]++; }else{ int t = h[x]; h[x] = i; a[i].first = y; a[i].second = t; in[y]++; } } priority_queue
, less
> que; for(int i=1;i<=n;i++) if(in[i] == 0) que.push(i); while( !que.empty()){ int top = que.top(); que.pop(); ans[cnt++] = top; for(int i = h[top];i!=0;i = a[i].second){ in[a[i].first]--; if(in[a[i].first] == 0) que.push(a[i].first); } } for(int i=cnt -1 ;i > 0;i--) printf("%d ",ans[i]); printf("%d\n",ans[0]); }}
View Code

 

转载于:https://www.cnblogs.com/star-and-me/p/7761529.html

你可能感兴趣的文章
ibatis学习笔记
查看>>
18-ES6(1)
查看>>
poj1611 简单并查集
查看>>
Ubuntu 14.04下安装CUDA8.0
查看>>
跨平台开发 -- C# 使用 C/C++ 生成的动态链接库
查看>>
C# BS消息推送 SignalR介绍(一)
查看>>
WPF星空效果
查看>>
WPF Layout 系统概述——Arrange
查看>>
PIGOSS
查看>>
几款Http小服务器
查看>>
iOS 数组排序
查看>>
第三节
查看>>
PHP结合MYSQL记录结果分页呈现(比较实用)
查看>>
Mysql支持的数据类型
查看>>
openSuse beginner
查看>>
Codeforces 620E(线段树+dfs序+状态压缩)
查看>>
Windows7中双击py文件运行程序
查看>>
Market entry case
查看>>
bzoj1230 开关灯 线段树
查看>>
LinearLayout
查看>>