题意:中文题
思路:我一直以为自己过掉了这个题,直到有天upc 训练时发现没过,现在打卡
这个题其实就是拓扑排序加上优先队列,因为我们对于没有入度的点呢,可以丢到优先队列中,这样就会弹出最小字典序(2018第一场多校耻辱下机,被1004卡3小时,思路差不多疯狂T)
代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <queue> using namespace std; const int maxn=30005; int n,m,ans; bool vis[maxn]; int in[maxn]; vector<int>edge[maxn]; int main() { int T; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); memset(in,0,sizeof(in)); for(int i=1;i<=n;i++)edge[i].clear(); for(int i=1;i<=m;i++){ int u,v; scanf("%d%d",&u,&v); in[u]++; edge[v].push_back(u); } // printf("test "); priority_queue<int> q; for(int i=1;i<=n;i++){ if(in[i]==0)q.push(i); } memset(vis,0,sizeof(vis)); vector<int>res; ans=0; // printf("test "); while(!q.empty()){ ans++; // printf("test %d %d ",ans,q.size()); int now=q.top(); res.push_back(now); q.pop(); vis[now]=1; for(int i=0;i<edge[now].size();i++){ int v=edge[now][i]; in[v]--; if(in[v]==0)q.push(v); } } // printf("test "); for(int i=res.size()-1;i>=0;i--){ if(i==res.size()-1) printf("%d",res[i]); else printf(" %d",res[i]); } puts(""); } return 0; }