题面
https://www.luogu.org/problem/CF555E
题解
#include<cstdio> #include<iostream> #include<vector> #include<algorithm> #include<cstring> using namespace std; struct stack{ int a[200050],tail; bool b[200050]; void clear() {memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); tail=0;} void push(int x) {++tail; a[tail]=x; b[x]=true;} int top() {return a[tail];} void pop() {b[a[tail]]=false; tail--;} bool isin(int x) {return b[x];} } stk; int n,m,q,dfn[200050],low[200050],cloct=0; int bel[200050],cnt=0; int s[200050],t[200050]; vector<int> to[200050],id[200050]; vector<int> about[200050]; int f[200050][25],d[200050]; int f1[200050],f2[200050]; bool ans; void tarjan(int now,int faid){ low[now]=dfn[now]=++cloct; stk.push(now); int i,l=to[now].size(); for (i=0;i<l;i++) if (id[now][i]!=faid) { if (!dfn[to[now][i]]) { tarjan(to[now][i],id[now][i]); low[now]=min(low[now],low[to[now][i]]); } else { if (stk.isin(to[now][i])) { low[now]=min(low[now],dfn[to[now][i]]); } } } if (low[now]==dfn[now]) { int x; ++cnt; do { x=stk.top(); bel[x]=cnt; stk.pop(); } while (x!=now); } } void maketree(int now,int fa,int deep){ int i,l=about[now].size(); f[now][0]=fa; for (i=1;i<=19;i++) f[now][i]=f[f[now][i-1]][i-1]; d[now]=deep; for (i=0;i<l;i++) if (about[now][i]!=fa) maketree(about[now][i],now,deep+1); } void work(int u,int v){ f1[u]+=1; f1[v]-=1; f2[u]+=1; f2[v]+=1; if (d[u]<d[v]) swap(u,v); int i,lca; for (i=19;i>=0;i--) if (d[f[u][i]]>=d[v]) u=f[u][i]; if (u==v) lca=u; else { for (i=19;i>=0;i--) if (f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i]; lca=f[u][0]; } f2[lca]-=2; } void treesum(int now,int fa) { int i,l=about[now].size(); for (i=0;i<l;i++) if (about[now][i]!=fa) { treesum(about[now][i],now); f1[now]+=f1[about[now][i]]; f2[now]+=f2[about[now][i]]; } if (abs(f1[now])!=abs(f2[now])) ans=false; } int main(){ int i,u,v,from,to0; scanf("%d %d %d",&n,&m,&q); for (i=1;i<=m;i++) { scanf("%d %d",&u,&v); s[i]=u; t[i]=v; to[u].push_back(v); id[u].push_back(i); to[v].push_back(u); id[v].push_back(i); } stk.clear(); for (i=1;i<=n;i++) if (!dfn[i]) tarjan(i,-1); for (i=1;i<=m;i++) { if (bel[s[i]]!=bel[t[i]]) { about[bel[s[i]]].push_back(bel[t[i]]); about[bel[t[i]]].push_back(bel[s[i]]); } } for (i=1;i<=cnt;i++) if (!f[i][0]) maketree(i,i,1); ans=true; for (i=1;i<=q;i++) { scanf("%d %d",&from,&to0); //printf("%d %d ",bel[from],bel[to0]); //printf("%d %d ",f[bel[from]][19],f[bel[to0]][19]); if (f[bel[from]][19]!=f[bel[to0]][19]) {ans=false; continue;} if (bel[from]!=bel[to0]) work(bel[from],bel[to0]); //val[from]=1; val[to]=-1; } //for (i=1;i<=n;i++) cout<<bel[i]<<" "; treesum(1,-1); if (ans) puts("Yes"); else puts("No"); }