51nod 1470 計算機網路問題
阿新 • • 發佈:2018-11-04
Solution
一個邊雙連通分量一定可以找到一個不走重複邊的環
這個的話用兩個之間一定存在至少兩條沒有公共邊的路徑可以得證
所以雙連通分量的所有點是可以隨便兩兩到達的
於是我們可以先來一發雙連通縮點
然後就變成了一個樹
差分一下
Code
#include<bits/stdc++.h>
using namespace std;
const int N=200001;
struct node{
int to,ne;
}e[N<<1],E[N<<1];
int h[N],low[N],dfn[N],st[N],top,bel[N] ,up[N],dn[N],lca,f[N][19],scc,dep[N],tim,n,m,q,i,x,y,tot,j,v,H[N],TOT;
bool fl;
inline char gc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int rd(){
int x=0,fl=1;char ch=gc();
for (;ch<48||ch>57;ch=gc())if(ch=='-' )fl=-1;
for (;48<=ch&&ch<=57;ch=gc())x=(x<<3)+(x<<1)+(ch^48);
return x*fl;
}
void add(int x,int y){
E[++TOT]=(node){y,H[x]};
H[x]=TOT;
}
void add1(int x,int y){
e[++tot]=(node){y,h[x]};
h[x]=tot;
}
void tarjan(int u,int fa){//因為有重邊,所以fa記錄上一條邊的編號
dfn[u]=low[u]=++tim;st[ ++top]=u;
for (int i=H[u],v;i;i=E[i].ne)
if (i!=fa)
if (!dfn[v=E[i].to]) tarjan(v,i^1),low[u]=min(low[u],low[v]);
else low[u]=min(low[u],dfn[v]);
if (low[u]==dfn[u]){
int x;scc++;
do{
x=st[top--];
bel[x]=scc;
}while (x!=u);
}
}
void dfs(int u,int fa){
f[u][0]=fa;
for (int i=1;i<19;i++) f[u][i]=f[f[u][i-1]][i-1];
for (int i=h[u],v;i;i=e[i].ne)
if ((v=e[i].to)!=fa) dep[v]=dep[u]+1,dfs(v,u);
}
int LCA(int x,int y){
if (dep[x]<dep[y]) swap(x,y);
for (int i=18;i>=0;i--)
if (dep[f[x][i]]>=dep[y]) x=f[x][i];
if (x==y) return x;
for (int i=18;i>=0;i--)
if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][0];
}
void solve(int u,int fa){
for (int i=h[u],v;i;i=e[i].ne)
if ((v=e[i].to)!=fa){
solve(v,u);
up[u]+=up[v];
dn[u]+=dn[v];
}
if (up[u]*dn[u]!=0) fl=0;
}
int main(){
n=rd();m=rd();q=rd();TOT=1;
for (i=1;i<=m;i++) x=rd(),y=rd(),add(x,y),add(y,x);
for (i=1;i<=n;i++)
if (!dfn[i]) tarjan(i,0);
for (i=1;i<=n;i++)
for (j=H[i];j;j=E[j].ne)
if (bel[i]!=bel[v=E[j].to]) add1(bel[i],bel[v]);
for (i=1;i<=scc;i++)
if (!dep[i]) dep[i]=1,dfs(i,0);
while (q--){
x=bel[rd()];y=bel[rd()];
lca=LCA(x,y);
if (!lca) return puts("No"),0;
up[x]++;up[lca]--;
dn[y]++;dn[lca]--;
}
fl=1;
solve(bel[1],0);
puts(fl?"Yes":"No");
}