萌新贪心求hack
查看原帖
萌新贪心求hack
1273313
Harumaki_Gohan楼主2024/11/23 10:41

rt,过了讨论区里找到的所有hack,还是只有10pts

做法是 yyxx 连有向边,先跑一遍dfs求出每个点能到达的编号最小的点 mn[u]mn[u],然后因为是 vector 存图,所以直接对每个vector排序,第一关键字是 mn[x]mn[x],第二关键字 xx,然后再来一遍dfs记录答案。

感觉真没啥问题了啊,求教/kel

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
const ll N=114514,M=1919810;
ll T;
ll n,m;
vector <ll> g[N],out;
bool vis[N],vi[N],flag;
ll mn[N];
void dfs1(ll u){
	if(flag) return;
	vi[u]=1,mn[u]=u;
	for(int v:g[u]){
		//cout<<"? "<<u<<" "<<v<<'\n';
		if(vis[v]) continue;
		if(vi[v]){
			flag=1;
			return;
		}
		dfs1(v);
		mn[u]=min(mn[u],mn[v]);
	}
	vis[u]=1;
}
bool cmp(ll x,ll y){
	return mn[x]^mn[y]?mn[x]<mn[y]:x<y;
}
void dfs(ll u){
	for(int v:g[u]){
		if(vis[v]) continue;
		dfs(v);
	}
	out.pb(u),vis[u]=1;
}
void solve(){
	cin>>n>>m;
	flag=0,out.clear();
	for(int i=1;i<=n;++i) g[i].clear(),vis[i]=vi[i]=0;
	for(int i=1;i<=m;++i){
		ll a,b;
		cin>>a>>b;
		g[b].pb(a);
	}
	for(int i=1;i<=n;++i)
		if(!vis[i]){
			dfs1(i);
			if(flag){
				cout<<"Impossible!\n";
				return;
			}
		}
	for(int i=1;i<=n;++i) sort(g[i].begin(),g[i].end(),cmp),vis[i]=0;
	for(int i=1;i<=n;++i)
		if(!vis[i]) dfs(i);
	for(int i:out) cout<<i<<" ";cout<<'\n';
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin>>T;
	while(T--) solve();
	return 0;
} 
2024/11/23 10:41
加载中...