CF555E. Case of Computer Network

题目大意

题解

缩点双前缀和判断,注意连通性与重边

code

#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
#define ll long long
//#define file
using namespace std;

int a[400001][2],ls[200001],num[200001],fa[200001][18],d[200001],f[200001][2],Num[200001],n,m,Q,i,j,k,l,x,y,z,len;
void New(int x,int y) {++len;a[len][0]=y;a[len][1]=ls[x];ls[x]=len;}
bool bz[200001];
namespace G{
	int a[400002][2],ls[200001],dfn[200001],low[200001],d[200002],len=1,i,j,k,l,tot;
	bool bz[200001];
	void New(int x,int y) {++len;a[len][0]=y;a[len][1]=ls[x];ls[x]=len;}
	
	void dfs(int Fa,int t)
	{
		int i;
		dfn[t]=low[t]=++j;
		bz[t]=1,d[++l]=t,d[l+1]=0;
		
		for (i=ls[t]; i; i=a[i][1])
		if ((i/2)!=Fa)
		{
			if (!dfn[a[i][0]])
			{
				dfs(i/2,a[i][0]),low[t]=min(low[t],low[a[i][0]]);
				if (dfn[t]<low[a[i][0]])
				{
					++tot;
					while (d[l+1]!=a[i][0])
					bz[d[l]]=0,num[d[l--]]=tot;
				}
			}
			else
			if (bz[a[i][0]])
			low[t]=min(low[t],dfn[a[i][0]]);
		}
		
		if (!Fa && l)
		{
			++tot;
			while (l)
			num[d[l--]]=tot;
		}
	}
};

void swap(int &x,int &y) {int z=x;x=y;y=z;}
int lca(int x,int y)
{
	int i;
	if (d[x]<d[y]) swap(x,y);
	fd(i,17,0) if (d[fa[x][i]]>=d[y]) x=fa[x][i];
	fd(i,17,0) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
	if (x!=y) x=fa[x][0];
	return x;
}
void dfs(int Fa,int t)
{
	int i;
	bz[t]=1,Num[t]=k,d[t]=d[Fa]+1;
	fa[t][0]=Fa;
	fo(i,1,17) fa[t][i]=fa[fa[t][i-1]][i-1];
	
	for (i=ls[t]; i; i=a[i][1])
	if (a[i][0]!=Fa && !bz[a[i][0]])
	dfs(t,a[i][0]);
}
void Dfs(int Fa,int t)
{
	int i;
	bz[t]=0;
	for (i=ls[t]; i; i=a[i][1])
	if (a[i][0]!=Fa && bz[a[i][0]])
	{
		Dfs(t,a[i][0]),f[t][0]+=f[a[i][0]][0],f[t][1]+=f[a[i][0]][1];
		if (f[a[i][0]][0] && f[a[i][0]][1])
		{
			printf("No
");
			exit(0);
		}
	}
}

int main()
{
	#ifdef file
	freopen("CF555E.in","r",stdin);
	#endif
	
	scanf("%d%d%d",&n,&m,&Q);
	fo(i,1,m) scanf("%d%d",&x,&y),G::New(x,y),G::New(y,x);
	
	fo(l,1,n)
	if (!G::dfn[l])
	G::dfs(0,l);
	fo(i,1,n)
	{
		for (j=G::ls[i]; j; j=G::a[j][1])
		if (num[i]<num[G::a[j][0]])
		New(num[i],num[G::a[j][0]]),New(num[G::a[j][0]],num[i]);
	}
	
	k=0;
	fo(l,1,n)
	if (!d[l])
	++k,dfs(0,l);
	for (;Q;--Q)
	{
		scanf("%d%d",&x,&y),x=num[x],y=num[y];
		if (Num[x]!=Num[y]) {printf("No
");return 0;}
		if (x!=y)
		l=lca(x,y),++f[x][0],--f[l][0],++f[y][1],--f[l][1];
	}
	Dfs(0,1);
	printf("Yes
");
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}
原文地址:https://www.cnblogs.com/gmh77/p/13669675.html