算得上是比较水的E题了吧,自己想了想写了写居然1A了

对于这道题,我们很容易想到对于原图的一个边双,定向后任意两点间一定可达

那么我们可以求出原图的边双并将每个边双缩成一个点

那么原图就变成了无环的无向图,也就是一片森林

之后我们考虑每个任务:

1、如果S和T处于一个边双里,显然是可行的

2、如果S和T处于两棵树中,显然不连通不可行

3、S和T处于一棵树中,那么S->lca的所有边都是向上的,lca->T的所有边的都是向下的

对于第三种情况,我们可以在S上打一个up标记,在T上打一个down标记

之后在lca上将传递过来的up和down清除即可

那么最后我们只需要对森林做一遍DFS即可判断可行性

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<stack>
using namespace std; const int maxn=200010;
int n,m,q;
int u,v;
struct Edge{
int u,v;
}c[maxn];
int h[maxn],cnt=1;
struct edge{
int to,next;
}G[maxn<<2];
int pre[maxn],low[maxn];
int dfs_clock=0,bcc_cnt=0;
int bccno[maxn],f[maxn];
int fa[maxn],anc[maxn][20];
int dep[maxn];
int up[maxn],down[maxn];
stack<int>S; int ufs(int x){return f[x]==x?x:f[x]=ufs(f[x]);}
void add(int x,int y){++cnt;G[cnt].to=y;G[cnt].next=h[x];h[x]=cnt;}
void DFS(int u,int f){
pre[u]=low[u]=++dfs_clock;S.push(u);
for(int i=h[u];i;i=G[i].next){
if(i==(f^1))continue;
int v=G[i].to;
if(!pre[v]){
DFS(v,i);
low[u]=min(low[u],low[v]);
}else if(!bccno[v])low[u]=min(low[u],pre[v]);
}
if(low[u]==pre[u]){
bcc_cnt++;
for(;;){
int now=S.top();S.pop();
bccno[now]=bcc_cnt;
if(now==u)break;
}
}return;
}
void Get_Tree(){
for(int i=1;i<=n;++i){
if(!pre[i])DFS(i,0);
}return;
}
void Get_DFS(int u,int f){
fa[u]=f;
for(int i=h[u];i;i=G[i].next){
int v=G[i].to;
if(v==f)continue;
dep[v]=dep[u]+1;
Get_DFS(v,u);
}return;
}
void pre_LCA(){
for(int i=1;i<=n;++i){
anc[i][0]=fa[i];
for(int j=1;(1<<j)<=n;++j)anc[i][j]=-1;
}
for(int j=1;(1<<j)<=n;++j){
for(int i=1;i<=n;++i){
if(anc[i][j-1]!=-1){
int a=anc[i][j-1];
anc[i][j]=anc[a][j-1];
}
}
}return;
}
int LCA(int p,int q){
if(dep[p]<dep[q])swap(p,q);
int log;
for(log=0;(1<<log)<=dep[p];++log);log--;
for(int i=log;i>=0;--i){
if(dep[p]-(1<<i)>=dep[q])p=anc[p][i];
}
if(p==q)return p;
for(int i=log;i>=0;--i){
if(anc[p][i]!=-1&&anc[p][i]!=anc[q][i]){
p=anc[p][i];q=anc[q][i];
}
}return fa[p];
}
void check(int u,int f){
for(int i=h[u];i;i=G[i].next){
int v=G[i].to;
if(v==f)continue;
check(v,u);
up[u]+=up[v];down[u]+=down[v];
}
if(up[u]>0&&down[u]>0){
printf("No\n");
exit(0);
}return;
} int main(){
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=m;++i){
scanf("%d%d",&c[i].u,&c[i].v);
add(c[i].u,c[i].v);add(c[i].v,c[i].u);
}
Get_Tree();
memset(h,0,sizeof(h));cnt=1;
for(int i=1;i<=n;++i)f[i]=i;
for(int i=1;i<=m;++i){
int a=bccno[c[i].u];
int b=bccno[c[i].v];
if(a!=b){
add(a,b);add(b,a);
int d1=ufs(a),d2=ufs(b);
if(d1!=d2)f[d1]=d2;
}
}
for(int i=1;i<=bcc_cnt;++i){
int rt=ufs(i);
if(rt==i)Get_DFS(rt,-1);
}
pre_LCA();
for(int i=1;i<=q;++i){
scanf("%d%d",&u,&v);
int a=bccno[u],b=bccno[v];
if(ufs(a)!=ufs(b)){printf("No\n");return 0;}
int lca=LCA(a,b);
up[a]++;down[b]++;up[lca]--;down[lca]--;
}
for(int i=1;i<=bcc_cnt;++i){
int rt=ufs(i);
if(rt==i)check(rt,-1);
}printf("Yes\n");return 0;
}

  

codeforces #310 div1 E的更多相关文章

  1. codeforces #310 div1 D

    一开始写了个暴力模拟绳子的摆动轨迹 然后在Test 16 T掉了 后来%了一下别人的代码,发现需要对特殊情况进行特殊处理 首先我们考虑绳子的向右摆动,设当前位置为p,绳子当前长度为L 如果其旋转中心位 ...

  2. codeforces #310 div1 C

    操作无论是U还是L,都会使原图形分裂成两个图形,且两个图形的操作互不影响 我们又发现由于操作点只可能在下斜线上,如果将操作按x排序 那么无论是U还是L,都会将操作序列完整分割成两半,且两个操作序列互不 ...

  3. codeforces #310 div1 B

    我们考虑n-1座桥每座桥需要的长度在一个区间[L,R]中 之后我们现在有m座桥,每个桥的长度为k 题意就是要求一个匹配方案 显然如果数据范围不大直接KM就可以了 可是20w的数据KM显然要T 所以我们 ...

  4. codeforces #310 div1 A

    首先我们考虑最暴力的拆解拼凑 显然拆分掉所有的链需要 n-m 次 之后拼凑需要 n-1 次 然后由题目规定可知:只有从1出发且连续的链不用拆掉,其余的都必须拆掉(因为两个都套有娃娃的套娃不能组合) 我 ...

  5. codeforces 407 div1 B题(Weird journey)

    codeforces 407 div1 B题(Weird journey) 传送门 题意: 给出一张图,n个点m条路径,一条好的路径定义为只有2条路径经过1次,m-2条路径经过2次,图中存在自环.问满 ...

  6. codeforces 407 div1 A题(Functions again)

    codeforces 407 div1 A题(Functions again) Something happened in Uzhlyandia again... There are riots on ...

  7. codeforces #313 div1 E

    首先我们要注意到一个事情 如果一个灯塔向左覆盖,那么比他小的某个灯塔如果向左覆盖的端点大于当前塔向左覆盖的端点,他一定向右覆盖 对于当前灯塔向右覆盖也是同理 那么我们只需要记录当前覆盖到的端点就可以完 ...

  8. codeforces #305 div1 done

    总算搞定了这一场比赛的题目,感觉收获蛮大 其中A,B,C都能通过自己的思考解决掉 D题思路好神,E题仔细想想也能想出来 以后坚持每两天或者一天做一场CF的div1的全套题目 除非有实在无法做出来的题目 ...

  9. Codeforces #254 div1 B. DZY Loves FFT 暴力乱搞

    B. DZY Loves FFT 题目连接: http://codeforces.com/contest/444/problem/B Description DZY loves Fast Fourie ...

随机推荐

  1. JavaScript学习笔记(13)——BOM

    1.window 所有浏览器都支持window对象,它表示浏览器窗口本身. 所有 JavaScript 全局对象.函数以及变量均自动成为 window 对象的成员. 全局变量是 window 对象的属 ...

  2. OC8_NSData

    // // main.m // OC8_NSData // // Created by zhangxueming on 15/6/19. // Copyright (c) 2015年 zhangxue ...

  3. java SimpleDateFormat非线程安全测试

    public class MyThread extends Thread { private SimpleDateFormat sdf; private String dateString; publ ...

  4. Spring Mvc模式下Jquery Ajax 与后台交互操作

    1.基本代码 1)后台控制器基本代码 @Controller @RequestMapping("/user") public class UserController { @Aut ...

  5. maven安装配置(myeclipse)(一)

    欢迎转载:http://www.cnblogs.com/shizhongtao/p/3374130.html 对于我来说,maven主要用于jar包的管理,避免项目中频繁更换jar的版本,以及网上搜索 ...

  6. POJ 2528 Mayor’s posters

    Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 37982   Accepted: 11030 ...

  7. 《QQ欢乐斗地主》山寨版

    使用Cocos2d-x编写,模仿<QQ欢乐斗地主>的界面实现了一个具有简单AI的单机版斗地主游戏. 游戏的详细说明请查看游戏目录下的help.txt文件. 下载地址: http://dow ...

  8. java-多线程-join函数

    join()>>不带参数 线程A调用线程B.join,意思就是线程A并入了线程B,当执行完线程B,再去执行线程A后续动作 join(int keepTims)>>带参数,与上面 ...

  9. 汇编语言-打印部分ASCII表

    用表格形式显示字符 1. 题目:用表格形式显示ASCII字符 2.要求:按15行×16列的表格形式显示ASCII码为10H-100H的所有字符,即以行为主的顺序及ASCII码递增的次序依次显示对应的字 ...

  10. html实现层叠加

    <div id="canvasesdiv" style="position:relative; width:400px; height:300px"> ...