1. 程式人生 > >51nod 1470 計算機網路問題

51nod 1470 計算機網路問題

題目
題解

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"); }