CF1450E Capitalism 题解

2022/9/14 23:20:47

本文主要是介绍CF1450E Capitalism 题解,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

首先发现这个 \(|a_i-a_j|=1\) 的形式比较接近差分约束,稍微转化一下就是:\(-1\le a_i-a_j\le 1\) 且 \(a_i\neq a_j\)。于是你会发现 \(a_i\neq a_j\) 不是差分约束的条件。

换个角度。容易发现一条边相连的两个点一定奇偶性不同。考虑原图中若存在奇环,那么显然这是自相矛盾的。所以我们可以一开始就把存在奇环的情况判一下。

再回头看 \(a_i\neq a_j\),你会发现在没有奇环的情况下,是不可能出现 \(a_i=a_j\) 的。原因仍然是一条边相连的两个点一定奇偶性不同。所以我们可以大胆地把条件改写为 \(-1\le a_i-a_j\le 1\)。

接下来用 Floyd 跑全源最短路,就可以得到一组解了。那么我们应该如何解决极差最大呢?考虑我们枚举最终极差最大的解中的最小值,以这个点为源点算出它和每个点的最短路。假设从 \(i\) 到 \(j\) 的最短路是 \(L\),它的实际含义是 \(a_j\le a_i+L\)。所以可以发现节点 \(j\) 的最大值就是 \(a_i+L\),所以用 \(L\) 更新极差是正确的。

最后输出答案,就是找到极差最大的那个源点,输出它到其他点的最短路。容易发现输出的所有数都是非负的,所以也不用加上一个特定的数。

// Author: Little09
// Problem: E. Capitalism
// Contest: Codeforces Global Round 12
// URL: https://codeforces.com/contest/1450/problem/E
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;

const int N=205,M=2005;
int n,m; 
int a[N],f[N][N],ans=-1,pos;
int fa[N*2];
int find(int x)
{
	if (x==fa[x]) return x;
	return fa[x]=find(fa[x]);
}
inline void merge(int x,int y)
{
	x=find(x),y=find(y);
	if (x!=y) fa[x]=y;
}
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cin >> n >> m;
	memset(f,20,sizeof(f));
	for (int i=1;i<=n;i++) f[i][i]=0;
	for (int i=1;i<=2*n;i++) fa[i]=i;
	for (int i=1;i<=m;i++)
	{
		int x,y,z;
		cin >> x >> y >> z;
		merge(x+n,y),merge(x,y+n);
		if (z==1) f[x][y]=1,f[y][x]=-1;
		else f[x][y]=1,f[y][x]=1;
	}
	for (int i=1;i<=n;i++)
	{
		if (find(i)==find(i+n))//存在奇环
		{
			cout << "NO";
			return 0;
		}
	}
	for (int k=1;k<=n;k++)//Floyd求全源最短路
	{
		for (int i=1;i<=n;i++)
		{
			for (int j=1;j<=n;j++)
			{
				f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
			}
		}
	}
	for (int i=1;i<=n;i++)
	{
		if (f[i][i]<0)//存在负环,差分约束无解
		{
			cout << "NO";
			return 0;
		}
		int mx=-n-1;
		for (int j=1;j<=n;j++) mx=max(mx,f[i][j]);
		if (mx>ans) ans=mx,pos=i;//找到最大值,更新极差
	}
	cout << "YES" << endl;
	cout << ans << endl;
	for (int i=1;i<=n;i++) cout << f[pos][i] << " ";
	return 0;
}



这篇关于CF1450E Capitalism 题解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程