比较简单的题。
考虑一个边双,我们可以巧妙给边定向让它变成一个强连通分量。做法是搞个dfs树,树边从父亲往儿子,非树边从儿子往父亲,容易证明这样一定合法。
于是我们可以把边双缩起来得到一棵树,问题就变成给树边定向,这个随便判一下就好了。
#include <bits/stdc++.h>
#define FR first
#define SE second
using namespace std;
typedef pair<int,int> pr;
struct Edge {
int t,next;
Edge() {}
Edge(int a,int b):t(a),next(b) {}
};
Edge e[400005];
int head[200005];
bool vis[200005];
int dfn[200005],low[200005],dfs_cnt;
void dfs1(int x,int fa) {
dfn[x]=low[x]=++dfs_cnt;
for(int i=head[x];i;i=e[i].next)
if (((i+1)>>1)!=fa) {
int u=e[i].t;
if (!dfn[u]) {
dfs1(u,(i+1)>>1);
low[x]=min(low[x],low[u]);
if (low[u]>dfn[x]) vis[(i+1)>>1]=1;
}
else low[x]=min(low[x],dfn[u]);
}
}
int id[200005],bcc_cnt;
vector <int> ee[200005];
void dfs2(int x) {
id[x]=bcc_cnt;
for(int i=head[x];i;i=e[i].next)
if (!id[e[i].t]&&!vis[(i+1)>>1]) dfs2(e[i].t);
}
int fa[200005][20],dep[200005],bel[200005],cnt;
int sum1[200005],sum2[200005];
void dfs3(int x) {
bel[x]=cnt;
for(int i=0;i<ee[x].size();i++)
if (ee[x][i]!=fa[x][0]) {
int u=ee[x][i];
fa[u][0]=x;dep[u]=dep[x]+1;
for(int j=1;j<20;j++) fa[u][j]=fa[fa[u][j-1]][j-1];
dfs3(u);
}
}
int lca(int x,int y) {
if (dep[x]<dep[y]) swap(x,y);
int d=dep[x]-dep[y];
for(int i=0;i<20;i++)
if ((d>>i)&1) x=fa[x][i];
if (x==y) return x;
for(int i=19;i>=0;i--)
if (fa[x][i]!=fa[y][i]) {
x=fa[x][i];
y=fa[y][i];
}
return fa[x][0];
}
void dfs4(int x) {
for(int i=0;i<ee[x].size();i++)
if (ee[x][i]!=fa[x][0]) {
int u=ee[x][i];
dfs4(u);
sum1[x]+=sum1[u];
sum2[x]+=sum2[u];
}
}
int main() {
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=m;i++) {
int x,y;
scanf("%d%d",&x,&y);
e[2*i-1]=Edge(y,head[x]);
head[x]=2*i-1;
e[2*i]=Edge(x,head[y]);
head[y]=2*i;
}
for(int i=1;i<=n;i++)
if (!dfn[i]) dfs1(i,0);
for(int i=1;i<=n;i++)
if (!id[i]) {
bcc_cnt++;
dfs2(i);
}
for(int i=1;i<=n;i++)
for(int j=head[i];j;j=e[j].next)
if (id[i]!=id[e[j].t]) ee[id[i]].push_back(id[e[j].t]);
for(int i=1;i<=bcc_cnt;i++)
if (!bel[i]) {
cnt++;
dfs3(i);
}
for(int i=1;i<=k;i++) {
int x,y;
scanf("%d%d",&x,&y);
x=id[x];y=id[y];
if (bel[x]!=bel[y]) {
puts("No");
return 0;
}
int p=lca(x,y);
sum1[x]++;sum1[p]--;
sum2[y]++;sum2[p]--;
}
for(int i=1;i<=bcc_cnt;i++)
if (!fa[i][0]) dfs4(i);
for(int i=1;i<=bcc_cnt;i++)
if (sum1[i]&&sum2[i]) {
puts("No");
return 0;
}
puts("Yes");
return 0;
}