CF555E 做题记录

首先缩点成一个 DAG,然后对于 \((s,t)\),设他们的 \(\operatorname{lca}\)\(x\),则有 \((s,x)\) 中的每条边会有一条种类的边,\((x,t)\) 会有另一种类的边,用树上差分计算即可。时间复杂度 \(O(m\log n)\),瓶颈是 LCA。

点击查看代码
#include<bits/stdc++.h>

#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
#define inn(i,n,a) For(i,1,n) a[i]=read();

#define ll long long
#define i128 __int128

using namespace std;
inline int read() {
	int xx= 0;int f= 1;
	char c = getchar();
	while(c<'0'||c>'9') { 
		if(c=='-') f= -1;
		c= getchar();
	}
	while(c>='0'&&c<='9') {
		xx= (xx<<1)+(xx<<3)+(c^48);
		c= getchar();
	}
	return xx*f;
}
#define maxn 200050
int n,m,q;
int u[maxn],v[maxn];
int st[maxn],ed[maxn];
vector<int>G[maxn],idx[maxn];
int edgecnt=1;
int dfn[maxn],low[maxn],dfncnt;
bool vis[maxn];
int stk[maxn],stktop;
int to_new[maxn],newcnt;
void dfs1(int u,int lst) {
	low[u]=dfn[u]=++dfncnt;
	vis[u]=1;
	stk[++stktop]=u;
	if(G[u].size()!=0) {
		For(i,0,((int)G[u].size())-1){
			int v=G[u][i],e=idx[u][i];
			if(e==(lst^1)) continue;
			if(!dfn[v]) dfs1(v,e),low[u]=min(low[u],low[v]);
			else if(vis[v]) low[u]=min(low[u],dfn[v]);
		}		
	}
	if(low[u]==dfn[u]) {
		newcnt++;
		while(1) {
			int v=stk[stktop--];
			vis[v]=0;
			to_new[v]=newcnt;
			if(u==v) break;
		}
	}
}
int lg2(int x) {
	int res=0;
	if(x&0xffff0000) res+=16,x>>=16;
	if(x&0x0000ff00) res+=8,x>>=8;
	if(x&0x000000f0) res+=4,x>>=4;
	if(x&0x0000000c) res+=2,x>>=2;
	if(x&0x00000002) res+=1,x>>=1;
	return res;
}
int fa[maxn][26],dep[maxn];
void dfs2(int u,int fath) {
	dep[u]=dep[fath]+1;
	fa[u][0]=fath;
	int k=lg2(dep[u]);
	For(i,1,k) fa[u][i]=fa[fa[u][i-1]][i-1];
	for(auto v:G[u]) if(v!=fath) dfs2(v,u);
}
int lca(int x,int y) {
	if(dep[x]<dep[y]) swap(x,y);
	while(dep[x]>dep[y]) x=fa[x][lg2(dep[x]-dep[y])];
	if(x==y) return x;
	int k=lg2(dep[x]);
	Rep(i,k,0) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
	return fa[x][0];
}
int to_cnt[maxn],re_cnt[maxn];
bool fin[maxn];
void dfs3(int u,int fath) {
	fin[u]=1;
	for(auto v:G[u]) if(v!=fath){
		dfs3(v,u);
		to_cnt[u]+=to_cnt[v];
		re_cnt[u]+=re_cnt[v];
	}
}
signed main() {
	in3(n,m,q);
	For(i,1,m) in2(u[i],v[i]),pb(G[u[i]],v[i]),pb(G[v[i]],u[i]),pb(idx[u[i]],++edgecnt),pb(idx[v[i]],++edgecnt);
	For(i,1,q) in2(st[i],ed[i]);
	For(i,1,n) if(!dfn[i]) dfs1(i,0);
//	puts("IAKIOI");
	For(i,1,m) u[i]=to_new[u[i]],v[i]=to_new[v[i]];
	For(i,1,newcnt) G[i].clear();
	For(i,1,m) if(u[i]!=v[i]) G[u[i]].push_back(v[i]),G[v[i]].push_back(u[i]);
//	For(i,1,n) cout<<to_new[i]<<' ';
	For(i,1,newcnt) if(!dep[i]) dfs2(i,0);
	For(i,1,m) {
		st[i]=to_new[st[i]],ed[i]=to_new[ed[i]];
		if(st[i]==ed[i]) continue;
		if(lca(st[i],ed[i])==0) return cout<<"No",0;
		to_cnt[st[i]]++,re_cnt[ed[i]]++;
		int x=lca(st[i],ed[i]);
		to_cnt[x]--;
		re_cnt[x]--;
	}
	For(i,1,newcnt) if(!fin[i]) dfs3(i,0);
	For(i,1,newcnt) if(to_cnt[i]>0&&re_cnt[i]>0) return cout<<"No",0;
	cout<<"Yes";
}
posted @ 2024-10-23 22:19  coding_goat_qwq  阅读(2)  评论(0编辑  收藏  举报