题目大意:给出n个球和m个关系,要你根据这些关系求出他们正确的序列,注意这里让你输出的是第i个球在最终序列里的位置。
算法思想:拓扑排序,注意一下反向建图,还有重边要判定一下,最后注意如果这个图是个环或者部分是环,就说明关系有矛盾,就输出-1。
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; int t,n,m; int a,b; bool visited[205],isOver; int p[205][205]; int sym; typedef struct Node { int indeer; int outdeer; int v; int now; bool operator < (const Node &n1) const { return n1.v>v; } }; Node nodes[205]; priority_queue<Node>que; void calc() { int flag=n; for(int i=1; i<=n; i++) { nodes[i].v=i; if(nodes[i].indeer==0) que.push(nodes[i]); } if(que.empty()) { isOver=true;//说明图中有环 return; } while(!que.empty()) { Node k=que.top(); que.pop(); flag--;//整个图没有环,但是,部分图可能有环 nodes[k.v].now=flag+1; for(int i=1; i<=n; i++) { if(p[i][k.v]) { nodes[k.v].outdeer--; nodes[i].indeer--; p[i][k.v]=0; if(nodes[i].indeer==0) que.push(nodes[i]); } } } if(flag!=0) { isOver=true; } } int main() { scanf("%d",&t); while(t--) { memset(visited,false,sizeof(visited)); memset(nodes,0,sizeof(nodes)); memset(p,0,sizeof(p)); sym=1; isOver=false; scanf("%d%d",&n,&m); for(int i=0; i<m; i++) { scanf("%d%d",&a,&b); if(p[a][b]==0) { p[a][b]=1; nodes[b].outdeer++; nodes[a].indeer++; } } calc(); if(isOver) printf("-1\n"); else { for(int i=1; i<n; i++) { printf("%d ",nodes[i].now); } printf("%d\n",nodes[n].now); } } return 0; }