给一些二元组,规定 \((u,v)\) 中,\(u\) 的出现顺序要高于 \(v\),并且要让值较小的尽量靠前出现,求最终的序列。
第一眼看着像最小字典序拓扑序,写了一下,发现过不去 \(3\) 测。考虑如何转化到一个好写的东西。
想让权值较小的数靠前出现,考虑权值较大的数,需要其在后面出现,并且较大的尽可能靠后。
于是将答案序列反转过来,需要较大的必须靠前,仔细思考这个与一开始的题目要求的区别。
但是题目中的 \((u,v)\),显然是不能使用的,于是见反边之后跑最大字典序拓扑序然后倒序输出即可。
\(code:\)
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+1000;
#define ll long long
#define L(i,j,k) for(int i=j;i<=k;i++)
int t;
int n,m;
vector<int> edge[N];
int in[N];
priority_queue<int> Queue;
vector<int> ans;
int main(){
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
#endif
ios::sync_with_stdio(0);
cin>>t;
while(t--){
L(i,1,n)edge[i].clear();
memset(in,0,sizeof(in));
ans.clear();
cin>>n>>m;
L(i,1,m){
int u,v;
cin>>u>>v;
edge[v].push_back(u);
in[u]++;
}
L(i,1,n){
if(!in[i])Queue.push(i);
}
while(!Queue.empty()){
int u=Queue.top();
Queue.pop();
for(int v: edge[u]){
if(!(--in[v])){
Queue.push(v);
}
}
ans.push_back(u);
}
int siz=ans.size();
if(siz==n)for(int i=siz-1;i>=0;i--)cout<<ans[i]<<' ';
else cout<<"Impossible!";
cout<<'\n';
}
return 0;
}
标签:LG,int,Queue,--,edge,ans,push,P3243
From: https://www.cnblogs.com/Pump-kin/p/18373945