把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

【洛谷6830】[IOI2020] 连接擎天树(趣题)

点此看题面

  • 有一张\(n\)个点的简单无向图,给定每对点之间的简单路径条数\(p_{i,j}\)
  • 求构造一张可能的图,或判断无解。
  • \(n\le10^3,\forall p\le3\)

对于\(p=1\)的情况

如果我们用并查集合并每一对\(p_{i,j}=1\)\(i,j\),显然如果并查集中一个连通块里存在两点之间\(p\not=1\),就必然无解。

考虑\(p=1\)意味着两点之间只有一条简单路径,故发现只要对每个连通块随便构造出一棵树,然后就可以把这整个块缩成一个点。

于是\(p=1\)的情况就不复存在了。

对于\(p=2\)的情况

同样,我们用并查集合并每一对\(p_{i,j}=2\)\(i,j\),显然如果并查集中一个连通块里存在两点之间\(p\not=2\)。就必然无解。

然后我们考虑每一个连通块,发现只要给这个连通块随便建一个环就可以了。

特别注意,如果一个连通块只有两个点,此时该连通块是无法构成环的。

对于\(p=3\)的情况

其实,只要存在\(p=3\),就必然无解。

如果存在\(p_{A,B}=3\),则下图是最简单的一种情况:

而此时,从\(C\)\(D\)存在\(4\)条路径(\(CAD,CBD,CABD,CBAD\)),超出了题目中给定的限制。

因此,\(p=3\)的情况不存在。

于是这道题就做完了。

代码:\(O(n^2)\)

#include "supertrees.h"
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 1000
#define Array vector<vector<int> >
using namespace std;
int n,w[N+5],k[N+5],c[N+5],f[N+5];I int fa(CI x) {return f[x]^x?f[x]=fa(f[x]):x;}//并查集
Array b;int construct(Array p)
{
	RI i,j,x,y;for(n=p[0].size(),b.resize(n),i=0;i^n;++i) f[i]=i,b[i].resize(n);//初始化
	for(i=0;i^n;++i) for(j=0;j^n;++j) if(p[i][j]==3) return 0;//如果存在3,必然无解
	for(i=0;i^n;++i) for(j=0;j^n;++j) p[i][j]==1&&(x=fa(i))^(y=fa(j))&&(f[x]=y,b[x][y]=b[y][x]=1);//把1在并查集上合并
	for(i=0;i^n;++i) for(j=0;j^n;++j) if(i^j&&p[i][j]^1&&fa(i)==fa(j)) return 0;//判断是否存在矛盾
	for(i=0;i^n;++i) w[i]=(k[i]=fa(i))==i;for(i=0;i^n;++i) f[i]=i;//k记录每个连通块的根,w记录每个点是否为根(缩点)
	for(i=0;i^n;++i) if(w[i]) for(j=0;j^n;++j) w[j]&&p[i][j]==2&&(x=fa(i))^(y=fa(j))&&(f[x]=y);//把2在并查集上合并
	for(i=0;i^n;++i) for(j=0;j^n;++j) if(k[i]^k[j]&&p[i][j]^2&&fa(k[i])==fa(k[j])) return 0;//判断是否存在矛盾
	for(i=0;i^n;++i) w[i]&&fa(i)^i&&(b[k[fa(i)]][i]=b[i][k[fa(i)]]=1,k[fa(i)]=i,++c[fa(i)]);//k记录上次连边的点,建环
	for(i=0;i^n;++i) if(w[i]&&fa(i)==i&&k[i]^i) {if(c[i]==1) return 0;b[k[i]][i]=b[i][k[i]]=1;}//如果存在两个点的环则无解,否则补全环
	return build(b),1;
}
posted @ 2021-02-03 20:31  TheLostWeak  阅读(62)  评论(0编辑  收藏  举报