ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF1450E Capitalism 题解

2022-09-14 21:33:18  阅读:178  来源: 互联网

标签:le int 题解 短路 CF1450E fa 极差 Capitalism find


首先发现这个 \(|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;
}

标签:le,int,题解,短路,CF1450E,fa,极差,Capitalism,find
来源: https://www.cnblogs.com/irty/p/16694581.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有