专栏文章

[AT_arc111_d] [ARC111D] Orientation 题解

AT_arc111_d题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@minagv1t
此快照首次捕获于
2025/12/01 23:13
3 个月前
此快照最后确认于
2025/12/01 23:13
3 个月前
查看原文
小清新思维题!
题目加粗了有解条件,这是一个关键信息。
注意到有向图形如若干个 SCC 缩点成一个 DAG,显然 SCC 内 cic_i 相等,而拓扑序下最大(即没有出度)的 SCC,其 cc 值必然是最小的,于是从小到大枚举 cc,对这些 cc 相等的点所在的 SCC,内部可以通过一遍 dfs 直接确定边的定向,对这些 SCC 向外连的还没有确定的边,直接连向这个 SCC 自身(保证拓扑序最大),不断模拟即可。
复杂度差不多是 O(n(n+m))\mathcal{O}(n(n+m)) 的。
codeCPP
#include<bits/stdc++.h>
#define pb emplace_back
#define mp make_pair
using namespace std;
typedef long long ll;
const ll maxn=107,ee=1e18,p=1e9+7;
struct Edge{ll v,id;};
ll n,m,c[maxn],ans[maxn*maxn],vis[maxn],col[maxn];
vector<Edge> edge[maxn];
vector<ll> vec;
void dfs(ll u){
	if(vis[u]) return;
	ll v,id,tid;
	vis[u]=1;
	for(auto x:edge[u]){
		v=x.v,id=x.id,tid=abs(id);
		if(!ans[tid]){
			if(col[v]){
				if(id>0) ans[tid]=1;
				else ans[tid]=-1;
				dfs(v);
			}else if(id>0) ans[tid]=-1;
			else ans[tid]=1;
		}
	}
}
int main(void){
	//freopen("data.in","r",stdin);
	//freopen("data.out","w",stdout);
	ios::sync_with_stdio(0),cin.tie(0);
	cin>>n>>m;
	for(ll i=1,u,v;i<=m;i++){
		cin>>u>>v;
		edge[u].pb(Edge{v,i}),edge[v].pb(Edge{u,-i});
	}
	for(ll i=1;i<=n;i++) cin>>c[i];
	for(ll t=1;t<=n;t++){
		for(ll i=1;i<=n;i++) vis[i]=col[i]=0;
		for(ll i=1;i<=n;i++)if(c[i]==t) vec.pb(i),col[i]=1;
		for(auto x:vec)if(!vis[x]) dfs(x);
	}
	for(ll i=1;i<=m;i++){
		if(ans[i]>0) cout<<"->\n";
		else cout<<"<-\n";
	}
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...