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\n");
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\n");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\n");
fclose(stdin);
fclose(stdout);
return 0;
}