Loading

LGJOI - 竞赛图【题解】

题意:一张竞赛图,你需要给每条边定向。然后进行 \(m\) 次边翻转,每次翻转边 \((u_i,v_i)\),你需要保证你构造的图在任何时候都不是强连通图。

\(1\le n\le 400,\space 0\le m\le 2n-14\)

考虑挖出一个连通块,这个连通块内的所有点总是向外连边,这样既可满足图永远不强连通的条件。

“挖连通块”非常抽象,具体的,我们先枚举第一个激活的点,用 \(vis[u]=0/1\) 表示 \(u\) 是否被激活。

依次枚举翻转的边,若这条边连的两个点有一个被激活,那么另一个也会被激活。最后判断是否存在未被激活的点,若是则枚举的点合法。

然后考虑构造,仍然枚举翻转的边。挖出的连通块内的边和连通块外的边方向随意,我们只需考虑连通块内的点与连通块外的点连接的边。

每激活一个点,我们确定一下令该点对当前连通块外的边的方向。注意考虑的边可能已经翻转过,所以还要记录每条边是否翻转过。

不会证,官方题解写得依托答辩。

#include<bits/stdc++.h>
#define pr pair<ll,ll>
#define x first
#define y second
#define mkp(a,b) make_pair(a,b)
#define pb push_back
#define ll long long
#define _CRT_SECURE_NO_WARNINGS
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
using namespace std;
const ll maxn=410;
ll n,m,w[maxn][maxn],ans[maxn][maxn],vis[maxn];
pr a[maxn];
void upd(ll x)
{
	for(ll i=1;i<=n;i++)
		if(!vis[i])
		{
			ans[x][i]=w[x][i]^1;
			ans[i][x]=w[x][i];
		}
}
int main()
{
	freopen("graph.in","r",stdin);
	freopen("graph.out","w",stdout);
	scanf("%lld%lld",&n,&m);
	for(ll i=1;i<=m;i++)
	{
		scanf("%lld%lld",&a[i].x,&a[i].y);
	}
	for(ll i=1;i<=n;i++)
	{
		memset(vis,0,sizeof vis);
		vis[i]=1;
		for(ll j=1;j<=m;j++)
		{
			pr e=a[j];
			if(vis[e.x]||vis[e.y])
				vis[e.x]=vis[e.y]=1;
		}
		if(count(vis+1,vis+1+n,0))
		{
			memset(vis,0,sizeof vis);
			vis[i]=1; upd(i);
			break;
		}
	}
	for(ll i=1;i<=m;i++)
	{
		pr e=a[i];
		w[e.x][e.y]^=1; w[e.y][e.x]^=1;
		if(vis[e.x]||vis[e.y])
		{
			if(!vis[e.x]) upd(e.x);
			else if(!vis[e.y]) upd(e.y);
			vis[e.x]=vis[e.y]=1;
		}
	}
	for(ll i=1;i<=n;i++)
	{
		for(ll j=i+1;j<=n;j++)
			printf("%lld ",ans[i][j]);
		printf("\n");
	}
	return 0;
}
posted @ 2023-10-08 15:14  Lgx_Q  阅读(16)  评论(0编辑  收藏  举报