hdu 4857 逃生(拓撲排序)
阿新 • • 發佈:2019-02-20
題意:給n個人,他們之間存在前後關係,某人必須在某人前面;如果兩個人之間不存在關係,則編號小的在前面,輸出符合條件的順序。
思路:開始的想法是建單向圖,按照拓撲排序,每次把入度為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[N],mark[N],ans[N]; 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; }