记录编号 390678 评测结果 AAAAAAAAAA
题目名称 [HZOI 2015]地牢里的背叛 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 0.836 s
提交时间 2017-04-03 17:58:27 内存使用 55.62 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int N=1e6+10;
int n,m,q,w[N],next[N],head[N];
bool vis[N];
void add(int f,int t){
	static int cnt=1;
	w[++cnt]=t;
	next[cnt]=head[f];
	head[f]=cnt;
}
int S[N],fa[N];
int find(int x){return S[x]==x?x:S[x]=find(S[x]);}
void dfs(int x){
	for (int i=head[x];i;i=next[i])
	if (!vis[i]){
		vis[i]=vis[i^1]=1;
		if (fa[w[i]]){
			for (int y=x;;){
				int v=find(y);y=fa[v];
				if (v==find(w[i])) break;
				S[v]=find(w[i]);
			}
		}
		else fa[w[i]]=x,dfs(w[i]);
	}
}
vector<int> E[N];
//tag为标记,即将区间置为某个值,v为这条边的值,-1:向下;1:向上 
int son[N][2],v[N],tag[N],id;
bool root[N],ise[N],rev[N],isdown[N],isup[N];
void visit(int x){
	root[x]=1;
	for (int i=E[x].size()-1;i>=0;i--){
		int v=E[x][i];
		if (!fa[v]){
			fa[fa[v]=++id]=x;
			root[id]=ise[id]=1;
			visit(v);
		}
	}
}
#define lc son[x][0]
#define rc son[x][1]
void update(int x){
	isup[x]=isdown[x]=0;
	if (lc) isdown[x]|=isdown[lc],isup[x]|=isup[lc];
	if (rc) isdown[x]|=isdown[rc],isup[x]|=isup[rc];
	if (v[x]>0) isup[x]=1;
	if (v[x]<0) isdown[x]=1;
}
void flip(int x){
	swap(lc,rc);
	swap(isdown[x],isup[x]);
	v[x]=-v[x];
	tag[x]=-tag[x];
	rev[x]^=1;
}
void paint(int x,int C){
	if (ise[x]) v[x]=C;
	tag[x]=C;
	C>0?isup[x]=1:isdown[x]=1;
}
void pushdown(int x){
	if (!x) return;
	if (rev[x]){
		if (lc) flip(lc);
		if (rc) flip(rc);
		rev[x]=0;
	}
	if (tag[x]){
		if (lc) paint(lc,tag[x]);
		if (rc) paint(rc,tag[x]);
		tag[x]=0;
	}
}
void rot(int x){
	int y=fa[x],z=fa[y];
	bool b=(x==son[y][1]);
	fa[son[y][b]=son[x][!b]]=y;
	fa[son[x][!b]=y]=x;
	fa[x]=z;
	if (y==son[z][0]) son[z][0]=x;else
	if (y==son[z][1]) son[z][1]=x;
	root[x]=root[y];root[y]=0;
	update(y);update(x);
}
void splay(int x){
	pushdown(x);
	for (;!root[x];rot(x)){
		int y=fa[x],z=fa[y];
		pushdown(z);pushdown(y);pushdown(x);
		if (root[y]) continue;
		rot((x==son[y][0])==(y==son[z][0])?y:x);
	}
}
void access(int x){
	splay(x);
	root[rc]=1;rc=0;
	update(x);
	while (fa[x]){
		int y=fa[x];
		splay(y);
		root[son[y][1]]=1;
		root[son[y][1]=x]=0;
		update(y);
		splay(x);
	}
}
int link[N];
int getset(int x){return link[x]==x?x:link[x]=getset(link[x]);}
int main()
{
	freopen("MM.in","r",stdin);
	freopen("MM.out","w",stdout);
	scanf("%d%d%d",&n,&m,&q);
	for (int i=1;i<=n;i++) S[i]=link[i]=i;
	for (int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y);add(y,x);
		link[getset(x)]=getset(y);
	}
	for (int i=1;i<=n;i++)
		if (!fa[i]) fa[i]=i,dfs(i);
	for (int i=1;i<=n;i++)
	for (int j=head[i];j;j=next[j]){
		int S=find(i),T=find(w[j]);
		if (S!=T){
			E[S].push_back(T);
			E[T].push_back(S);
		}
	}
	for (int i=1;i<=n;i++) fa[i]=0;id=n;
	for (int i=1;i<=n;i++)
		if (!fa[i]) fa[i]=i,visit(i),fa[i]=0;
	while (q--){
		int x,y;
		scanf("%d%d",&x,&y);
		if (getset(x)!=getset(y)) puts("No"),exit(0);
		x=find(x);y=find(y);
		if (x==y) continue;
		access(x);
		flip(x);
		access(y);
		if (isup[y]) puts("No"),exit(0);
		paint(y,-1);
	}
	puts("Yes");
	return 0;
}