555E Case of Computer Network
分析
一个连通块内的肯定不影响
于是我们先缩点
之后对于每个路径
向上向下分别开一个差分数组
如果两个数组同时有值则不合法
代码
#include<bits/stdc++.h>
using namespace std;
int n,m,q,bl[200100],s[200100],t[200100],dfn[200100],low[200100],is[200100];
int cnt,tot,sum,head[200100],nxt[400100],to[400100],ano[400100];
int d1[200100],d2[200100],dep[200100],pr[200100][23];
int f[200100],vis[200100],vis2[200100];
vector<int>v[200100];
stack<int>a;
inline int sf(int x){return f[x]==x?x:f[x]=sf(f[x]);}
inline void add(int x,int y){
nxt[++tot]=head[x],head[x]=tot,to[tot]=y,ano[tot]=tot+1;
nxt[++tot]=head[y],head[y]=tot,to[tot]=x,ano[tot]=tot-1;
}
inline void tarjan(int x,int id){
dfn[x]=low[x]=++cnt;
a.push(x),is[x]=1;
for(int i=head[x];i;i=nxt[i])
if(i!=ano[id]){
if(!dfn[to[i]]){
tarjan(to[i],i);
low[x]=min(low[x],low[to[i]]);
}else if(is[to[i]]){
low[x]=min(low[x],dfn[to[i]]);
}
}
if(low[x]==dfn[x]){
sum++;
while(1){
int u=a.top();
a.pop(),is[u]=0;
bl[u]=sum;
if(u==x)break;
}
}
}
inline void dfs(int x,int fa){
vis2[x]=1;
pr[x][0]=fa;
dep[x]=dep[fa]+1;
for(int i=0;i<v[x].size();i++)
if(v[x][i]!=fa)dfs(v[x][i],x);
}
inline int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
int i,j,k,len=dep[x]-dep[y];
for(i=0;i<=20;i++)
if((1<<i)&len)x=pr[x][i];
if(x==y)return x;
for(i=20;i>=0;i--)
if(pr[x][i]!=pr[y][i])
x=pr[x][i],y=pr[y][i];
return pr[x][0];
}
inline void dfs2(int x,int fa){
vis[x]=1;
for(int i=0;i<v[x].size();i++)
if(v[x][i]!=fa)dfs2(v[x][i],x),d1[x]+=d1[v[x][i]],d2[x]+=d2[v[x][i]];
if(d1[x]>0&&d2[x]>0){
puts("No");
exit(0);
}
}
int main(){
int i,j,k;
scanf("%d%d%d",&n,&m,&q);
for(i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
if(sf(x)!=sf(y))f[sf(x)]=sf(y);
}
for(i=1;i<=q;i++)scanf("%d%d",&s[i],&t[i]);
for(i=1;i<=q;i++)if(sf(s[i])!=sf(t[i])){puts("No");return 0;}
for(i=1;i<=n;i++)if(!dfn[i])tarjan(i,0);
for(i=1;i<=n;i++)
for(j=head[i];j;j=nxt[j])
if(bl[i]!=bl[to[j]])v[bl[i]].push_back(bl[to[j]]);
for(i=1;i<=sum;i++)if(!vis2[i])dfs(i,0);
for(i=1;i<=20;i++)
for(j=1;j<=sum;j++)
pr[j][i]=pr[pr[j][i-1]][i-1];
for(i=1;i<=q;i++){
if(bl[s[i]]==bl[t[i]])continue;
int x=bl[s[i]],y=bl[t[i]],z=lca(x,y);
d1[x]++,d1[z]--;
d2[y]++,d2[z]--;
}
for(i=1;i<=sum;i++)if(!vis[i])dfs2(i,0);
puts("Yes");
return 0;
}