[JZOJ 5895]【NOIP2018模拟10.5】旅游

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hzj1054689699/article/details/82945149

Description

给出一个n个点,m条边的无向图,保证无重边自环,第i条边的长度为 2 i 2^i
现在需要你找一条从1号点出发从1号点结束的回路,保证每条边至少经过一次,可以重复经过。求回路长度的最小值。
n , m 5 1 0 5 n,m\leq 5*10^5

Solution

考虑一个无向图存在欧拉回路的条件:每个点的度数均为偶数
定义度数为偶数的点为偶点,相应的定义奇(ji,一声)点
那么我们将所有奇点提出来,要将它们变成偶点。

相当于我们要在这些奇点之间连边,长度为它们之间的最短路,要连总长最少的边使得所有奇点都变成偶点。
答案就是原本所有的边权和+我们新连的边

根据最短路的性质,若存在边(x,y),(y,z),(y,p),那么不如连(x,z),(y,p),因为dis(x,y)+dis(y,z)>=dis(x,z)(相当于枚举中转点,联想Floyd算法)
这样一来,我们连的边必然是一个完美匹配(即两两匹配,每个点会且只会匹配另一个)

这么一来好像变成了带边权完全图的最小权最大匹配
好像是什么带花树?好像还是N^3的?(逃)
这可是NOIP!

咦我们发现,边权有问题
第i条边的长度为2^i
也就是说,所有小的加起来都不如一个大的大
那么路径一定就在最小生成树上了。。。

我们不妨先任意匹配这些奇点
此时我们考虑两个匹配(x,y),(p,q)
如果它们路径有重叠那肯定不优,因为一定可以重组变成没有重叠
发现这和树上路径的异或很像。
任意匹配,将每一组奇点在最小生成树上的路径标记,如果一条边被标记了奇数次则计入答案

然而有一种更机智的做法。
在每个奇点都打上1的标记,DFS最小生成树,如果某个点i为根的子树中标记的异或值为1则答案需要加上i到i父亲这条边的边权
这与上面的过程是等价的

由于边权是按顺序2^i给出的,我们连排序都省了。
复杂度 O ( n α ( n ) + m ) O(n\alpha(n)+m)

Code

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
#define LL long long
#define mo 998244353
#define N 500005
using namespace std;
int m1,n,m,rd[N],fs[N],pr[2*N],nt[2*N],dt[2*N],d[N],d1[N],bz[N],f[N],a1[N][2];
LL ans,cf[N];
void link(int x,int y,int z)
{
	nt[++m1]=fs[x];
	dt[fs[x]=m1]=y;
	pr[m1]=z;
}
int getf(int k)
{
	if(!f[k]) return k;
	return f[k]=getf(f[k]);
}
void dfs(int k,int fa,LL s)
{
	for(int i=fs[k];i;i=nt[i])
	{
		int p=dt[i];
		if(p!=fa) dfs(p,k,pr[i]),bz[k]^=bz[p];
	}
	if(bz[k]) ans=(ans+s)%mo;
}
int main()
{
	cin>>n>>m;
	fo(i,1,m)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		a1[i][0]=x,a1[i][1]=y;
		rd[x]++,rd[y]++;
	}
	fo(i,1,n) if(rd[i]&1) bz[i]=1;
	int j=0;
	cf[0]=1;
	ans=0;
	fo(i,1,m) cf[i]=cf[i-1]*(LL)2%mo,ans=(ans+cf[i])%mo;
	fo(i,1,m)
	{
		int fx=getf(a1[i][0]),fy=getf(a1[i][1]);
		if(fx!=fy)
		{
			f[fx]=fy;
			link(a1[i][0],a1[i][1],cf[i]);
			link(a1[i][1],a1[i][0],cf[i]);
		}
	}
	dfs(1,0,0);
	printf("%lld\n",ans);
}

猜你喜欢

转载自blog.csdn.net/hzj1054689699/article/details/82945149