hdu 4857 逃生(拓扑排序)
2014-09-08 23:55
441 查看
题意:给n个人,他们之间存在前后关系,某人必须在某人前面;如果两个人之间不存在关系,则编号小的在前面,输出符合条件的顺序。
思路:开始的想法是建单向图,按照拓扑排序,每次把入度为0的点加入到优先队列里面,测试通过,提价wa。想不明白为什么会wa,看了下discuss里面给出的样例,发现对于两个没有关系的点,编号小的必须在编号大的前面。
3 2
3 1
3 1
应该输出的是3 1 2,而不是2 3 1。这样的话就应该改为逆向建图,逆序输出,其他地方不变。提交之后AC。
思路:开始的想法是建单向图,按照拓扑排序,每次把入度为0的点加入到优先队列里面,测试通过,提价wa。想不明白为什么会wa,看了下discuss里面给出的样例,发现对于两个没有关系的点,编号小的必须在编号大的前面。
3 2
3 1
3 1
应该输出的是3 1 2,而不是2 3 1。这样的话就应该改为逆向建图,逆序输出,其他地方不变。提交之后AC。
#include<stdio.h> #include<string.h> #include<queue> using namespace std; const int N=30005; const int M=100005; struct edge { int son; int next; } Edge[M]; int head ,mark ,ans ; int cnt; int n,m; void AddEdge(int x,int y) { Edge[cnt].son=y,Edge[cnt].next=head[x],head[x]=cnt++; return ; } void topo() { priority_queue< int >q; for(int i=1; i<=n; i++) { if(!mark[i]) q.push(i); } int k=0; while(!q.empty()) { int father=q.top(); q.pop(); ans[k++]=father; for(int i=head[father]; i!=-1; i=Edge[i].next) { int son=Edge[i].son; mark[son]--; if(!mark[son])q.push(son); } } return ; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); memset(mark,0,sizeof(mark)); cnt=1; for(int i=1; i<=m; i++) { int x,y; scanf("%d%d",&x,&y); AddEdge(y,x); mark[x]++; } topo(); for(int i=n-1; i>0; i--) printf("%d ",ans[i]); printf("%d\n",ans[0]); } return 0; }
相关文章推荐
- HDU-4857逃生(反向拓扑排序)(重点是思想)
- hdu 4857 逃生(拓扑排序)
- hdu 4857 逃生 拓扑排序
- HDU 4857 逃生 拓扑排序+反向建图
- hdu 4857 逃生(拓扑排序)
- hdu 4857 逃生(拓扑排序)
- 逃生 HDU - 4857 拓扑排序
- HDU 4857-逃生(反向拓扑排序-按条件排序)
- hdu-----(4857)逃生(拓扑排序)
- hdu 4857 逃生(拓扑排序)
- hdu 4857 逃生(逆向拓扑排序)(STL应用)
- HDU 1285 确定比赛名次 + HDU 4857 逃生(拓扑排序由浅入深)
- hdu 4857 逃生(拓扑排序)
- HDU 4857 逃生(反向拓扑排序)
- HDU 4857 逃生 【拓扑排序+反向建图+优先队列】
- hdu-4857-逃生-拓扑排序
- HDU-#4857 逃生(拓扑排序)
- hdu 4857 逃生(拓扑排序)
- hdu 4857 逃生【反向拓扑排序】
- hdu 4857 逃生(拓扑排序)