LG - P3243

给一些二元组,规定 \((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;
}
posted @ 2024-08-22 15:17  Pump_kin  阅读(1)  评论(0编辑  收藏  举报