关于竞赛图


竞赛图(有向完全图)

竞赛图也叫有向完全图。每对顶点之间都有一条边相连的有向图称为竞赛图。

竞赛图的一些简单的性质:

  • 竞赛图没有自环,没有二元环;若竞赛图存在环,则一定存在三元环。(如果存在一个环大于三元,那么一定存在另一个三元的小环。)

  • 任意竞赛图都有哈密顿路径(经过每个点一次的路径,不要求回到出发点)。

  • 图存在哈密顿回路的充要条件是强联通。

  • 哈密顿问题中,对于 n 阶竞赛图,当 n 大于等于 2 时一定存在哈密顿通路。

\(D\)\(n\) 阶有向简单图,若 \(D\) 的基图为 \(n\) 阶无向完全图,则 \(D\)\(n\) 阶竞赛图。

简单来说,竞赛图就是将完全无向图的无向边给定了方向。

一、兰道定理

兰道定理(\(\text{Landau’s Theorem}\))是用来判定竞赛图的定理。

定义

定义一个竞赛图的比分序列(\(\text{score sequence}\)),是把竞赛图的每一个点的出度从小到大排列得到的序列。

定理内容

一个长度为 \(n\) 的序列 \(s=(s_1≤s_2,≤...≤s_n)\)\(n≥1\),是合法的比分序列当且仅当:

\[?1≤k≤n,∑_{i=1}^k\limits s_i≥{k\choose 2} \]

\(k=n\) 时这个式子必须取等号。

定理证明

首先这个定理的必要性是显然的:即任一 \(n\) 阶竞赛图都满足这个条件。

现在我们只需要证明这个定理的充分性。

在这里,我们的证明是一个构造算法。思路是从一个一般竞赛图开始,每次改变两条边的方向,构造出一个比分序列是给定序列的竞赛图。

假设有一个一个满足定理条件的序列 \(s\)。现在我们构造一个及其平凡的 \(n\) 阶竞赛图 \(T_n\),这个竞赛图的第 \(i\) 个节点向所有 \(j\(j\) 节点都连有向边,因此其比分序列是 \((0,1,...,n?1)\),我们要从这个平凡竞赛图开始构造。

考虑当前构造到了一个竞赛图 \(U\),它的比分序列 \(u\) 满足:

\[?1≤k≤n,∑_{i=1}^k\limits s_i≥∑_{i=1}^k\limits u_i \]

显然初始时 \(T_n\) 是满足这个条件的。

\(α\) 为第一个满足 \(s_α>u_α\) 的位置,这个位置显然存在不然就代表我们构造成功了。令 \(β\) 表示最后一个满足 \(u_α=u_β\) 的位置。

再考虑 \(γ\) 是第一个满足 \(s_γ 的位置,这个位置肯定要严格大于 \(β\),而且这个位置为什么一定存在呢?因为 \(∑^n_{i=1}\limits s_i=∑^k_{i=1}\limits u_i\) ,但是 \(β\) 及其以前的位置 \(s\) 都是要大于等于 \(u\) 的。

我们画一下这些位置大概是这样排列的

\[\begin{matrix} u_1 & u_2 & ... & u_\alpha &=& u_{\alpha+1} &=& ... &=& u_\beta&< & u_{\beta+1} & ... & u_{\gamma-1} &<& u_\gamma& ... &u_n\\ || & ||& ...& \land &&\land& & ... &&\land &&\land 或者|| &... &\land 或者|| &&\lor &...& ?\\ s_1 & s_2 & ... & s_\alpha & &s_{\alpha+1} && ...& & s_\beta && s_{\beta+1} & ... &s_{\gamma-1} && s_\gamma &... & s_n \end{matrix} \]

然后显然我们可以得到 \(u_γ>s_γ≥s_β>u_β\),即 \(u_γ≥u_β+2\) 这个意味着什么呢?

考虑点 \(γ\) 和点 \(β\)\(γ\) 的出度比 \(β\)\(2\),说明肯定至少有一个点 \(λ\) 满足 \(γ\) 向其连边而 \(β\) 没有向其连边(那么 \(λ\) 一定会向 \(β\) 连边),为什么要至少大 \(2\) 才满足呢?因为如果恰好大 \(1\) 的话多出来的这条边有可能是 \(γ\) 连向 \(β\),这么 \(λ\) 这个点的存在性就不好说。

于是我们说明了至少存在一个 \(λ(λ≠β,λ≠γ)\) 满足存在有向边 \((γ,λ)\)\((λ,β)\)

考虑翻转这两条边,然后得到一个新的竞赛图,简单推导就可以发现它的比分序列 \(u′\) 一定仍然满足。

\[\forall 1\le k\le n,\sum_{i=1}^ks_i\ge\sum_{i=1}^ku'_i \]

且依然在 \(n=k\) 时一定取等号。

这样我们可以构造出一个新的竞赛图,可是为什么一直这样做就可以得到一个比分序列是 \(s\) 的竞赛图呢?

考虑定义两个竞赛图的曼哈顿距离

\[dist(u.s)=∑_{i=1}^n\limits |s_i?u_i| \]

显然,经过我的边翻转操作之后一定有 \(dist(u′,s)=dist(u,s)?2\)。并且任意时候由于 \(∑^n_{i=1}\limits s_i=∑^n_{i=1}\limits u_i\),一定有 \(dist(u,s)≡0\pmod2\)(模 \(2\) 意义下可以拆开绝对值符号)。也就是说\(\dfrac{dist(u,s)}{2}\) 步我就可以构造出 \(s\) 序列所对应的竞赛图。

二、哈密顿路

定理 1. 竞赛图强连通缩点后的DAG呈链状, 前面的所有点向后面的所有点连边

证明:

考虑归纳, 逐连通块加入,目前有一条链, 插入一个新连通块 \(x\) ,如果 \(x\) 连向所有点, 放在链头

如果所有点连向 \(x\), 放在链尾,否则 \(x\) 的出边一定都在 \(x\) 的入边的后边 (否则成环)

找到分界点, 把 \(x\) 插在中间即可。

定理 2. 竞赛图的强连通块,存在一条哈密顿回路

证明:

考虑归纳, 逐点加入,目前有一条链, 链上的每个强连通块都存在哈密顿回路。

插入一个新点 \(x\), 只需证明新图中的强连通块都存在哈密顿回路即可。

如果不产生新连通块, 就是定理 \(1\) 中讨论的情况, 否则一定存在一条 \(x\) 的出边在 \(x\) 入边左边, 随便找一对。

如果是连到不同连通块, 见左图。

如果是同一连通块, 必定存在符合环的走向的相邻的一入一出, 见右图。

inline vector solve(vector vec){
	if(vec.size() == 1) return vec;
	vector t;
	for(auto it:vec) t.insert(find_if(t.begin(), t.end(), [&](int x){return g[it][x];}), it);
	auto it = find_if(t.begin(), t.end(), [&](int x){return g[x][t[0]];}) + 1;
	vector res(t.begin(), it);
	while(it != t.end()){
		auto r = it;
		while(find_if(res.begin(), res.end(), [&](int x){return g[*r][x];}) == res.end()) ++r;
		auto p = res.begin();
		while(p != res.end() && p + 1 != res.end() && !(g[*p][*it] && g[*r][*(p+1)])) ++p;
		res.insert(p == res.end() ? res.begin() : p + 1, it, r + 1); it = r + 1;
	}
	return res;
}

定理 3. 任意竞赛图都存在一条哈密顿路径

证明:

如图示方法构造:

for(int i = 1; i <= n; i++) if(!dfn[i]) tarjan(i);
for(int i = 1; i <= n; i++) Scc[scc[i]].push_back(i);
for(int i = 1; i <= tot; i++){
	Scc[i] = solve(Scc[i]);
	ans.insert(ans.end(), Scc[i].begin(), Scc[i].end());
	}
}

[POI2017]Turysta

给出一个 \(n\) 个点的有向图,任意两个点之间有且仅一条有向边。

对于每个点 \(v\),求出从 \(v\) 出发的一条经过点数最多,且没有重复经过同一个点两次及两次以上的简单路径。

\(\ge 3\) 个点的强连通竞赛图有哈密顿回路,因此从 \(u\) 开始最长的路径就是拓扑序在 \(u\) 所属的强连通分量之后 (包括其本身) 的强连通分量的哈密顿路径相连。在每个强连通分量找到哈密顿回路即可。

点击查看代码
#include
using namespace std;
int n;
int g[2005][2005];
int dfn[2005],low[2005],cnt,scc[2005],tot,stk[2005],top;
void tarjan(int x){
	dfn[x]=low[x]=++cnt;stk[++top]=x;
	for(int u=1;u<=n;u++){
		if(!g[x][u])continue;
		if(!dfn[u]){
			tarjan(u);low[x]=min(low[x],low[u]);
		}
		else if(!scc[u])low[x]=min(low[x],dfn[u]);
	}
	if(dfn[x]==low[x]){
		scc[x]=++tot;
		while(stk[top]!=x)scc[stk[top--]]=tot;
		top--;
	}
}
vector Scc[2005],ans[2005];
inline vector solve(vector vec){
	if(vec.size()==1)return vec;
	vector tmp;
	for(auto it:vec)tmp.insert(find_if(tmp.begin(),tmp.end(),[&](int x){return g[it][x];}),it);
	auto it=find_if(tmp.begin(),tmp.end(),[&](int x){return g[x][tmp[0]];})+1;
	vector res(tmp.begin(),it);
	while(it!=tmp.end()){
		auto r=it;
		while(find_if(res.begin(),res.end(),[&](int x){return g[*r][x];})==res.end())++r;
		auto p=res.begin();
		while(p!=res.end()&&p+1!=res.end()&&!(g[*p][*it]&&g[*r][*(p+1)]))++p;
		res.insert(p==res.end()?res.begin():p+1,it,r+1);it=r+1;
	}
	return res;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		for(int j=1;j

P4233 射命丸文的笔记

从所有含有 \(n\) 个顶点(顶点互不相同)的,值得记录的竞赛图中等概率随机选取一个。

求选取的竞赛图中哈密顿回路数量的期望值。

Solution

首先算出不同的哈密顿回路的总数量,任意地选取一个环,方案数为 \((n-1)!\times 2^{\binom{n}{2}-n}\) ,即圆排列数乘边数。

\(g_i\) 表示有 \(i\) 个点的竞赛图的数量,\(g_i=2^{\binom{i}{2}}\)

\(f_i\) 表示有 \(i\) 个点的竞赛图强联通的方案数。

由于竞赛图缩点后会形成链状 \(\text{DAG}\),枚举第一个连通块的大小来转移。

\[g_i=\sum_{j=1}^{i}\binom{i}{j}f_jg_{i-j} \\ g_i=\sum_{i=1}^{i}\frac{i!}{j!(i-j)!}f_jg_{i-j} \\ \frac{g_i}{i!}=\sum_{j=1}^{i}{\frac{f_j}{j!}\times\frac{g_{i-j}}{(i-j)!}} \]

\(F(x)=\sum_{i=1}^{n}{\frac{f_i}{i!}x^i}\)\(G(x)=\sum_{i=0}^{n}{\frac{g_i}{i!}}\)

\[G(x)=F(x)G(x)+1 \\ F(x)=1-\frac{1}{G(x)} \]

多项式求逆即可解决,时间复杂度为 \(O(n\log n)\)

点击查看代码
#include
using namespace std;
int n;
const int md=998244353,G=3,Gi=(md+1)/3;
int r[1<<20];
inline int pwr(int x,int y){
	int res=1;
	while(y){
		if(y&1)res=1ll*res*x%md;
		x=1ll*x*x%md;y>>=1;
	}
	return res;
}
inline void NTT(int *dp,int lim,int W){
	for(int i=0;i<(1<>1]>>1)+((i&1)<<(lim-1));
	for(int i=0;i>1);
	mul(f,g,lim,lim);
	for(int i=0;i=1)puts("1");
	if(n>=2)puts("-1");
	for(int i=3;i<=n;i++){
		int Pw=(1ll*i*(i-1)/2-i)%(md-1),w=1ll*fac[i-1]*pwr(2,Pw)%md;
		printf("%lld\n",1ll*w*pwr(f[i],md-2)%md);
	}


	return 0;
}

相关