codeforces #310 div1 E
算得上是比较水的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的更多相关文章
- codeforces #310 div1 D
一开始写了个暴力模拟绳子的摆动轨迹 然后在Test 16 T掉了 后来%了一下别人的代码,发现需要对特殊情况进行特殊处理 首先我们考虑绳子的向右摆动,设当前位置为p,绳子当前长度为L 如果其旋转中心位 ...
- codeforces #310 div1 C
操作无论是U还是L,都会使原图形分裂成两个图形,且两个图形的操作互不影响 我们又发现由于操作点只可能在下斜线上,如果将操作按x排序 那么无论是U还是L,都会将操作序列完整分割成两半,且两个操作序列互不 ...
- codeforces #310 div1 B
我们考虑n-1座桥每座桥需要的长度在一个区间[L,R]中 之后我们现在有m座桥,每个桥的长度为k 题意就是要求一个匹配方案 显然如果数据范围不大直接KM就可以了 可是20w的数据KM显然要T 所以我们 ...
- codeforces #310 div1 A
首先我们考虑最暴力的拆解拼凑 显然拆分掉所有的链需要 n-m 次 之后拼凑需要 n-1 次 然后由题目规定可知:只有从1出发且连续的链不用拆掉,其余的都必须拆掉(因为两个都套有娃娃的套娃不能组合) 我 ...
- codeforces 407 div1 B题(Weird journey)
codeforces 407 div1 B题(Weird journey) 传送门 题意: 给出一张图,n个点m条路径,一条好的路径定义为只有2条路径经过1次,m-2条路径经过2次,图中存在自环.问满 ...
- codeforces 407 div1 A题(Functions again)
codeforces 407 div1 A题(Functions again) Something happened in Uzhlyandia again... There are riots on ...
- codeforces #313 div1 E
首先我们要注意到一个事情 如果一个灯塔向左覆盖,那么比他小的某个灯塔如果向左覆盖的端点大于当前塔向左覆盖的端点,他一定向右覆盖 对于当前灯塔向右覆盖也是同理 那么我们只需要记录当前覆盖到的端点就可以完 ...
- codeforces #305 div1 done
总算搞定了这一场比赛的题目,感觉收获蛮大 其中A,B,C都能通过自己的思考解决掉 D题思路好神,E题仔细想想也能想出来 以后坚持每两天或者一天做一场CF的div1的全套题目 除非有实在无法做出来的题目 ...
- Codeforces #254 div1 B. DZY Loves FFT 暴力乱搞
B. DZY Loves FFT 题目连接: http://codeforces.com/contest/444/problem/B Description DZY loves Fast Fourie ...
随机推荐
- C++函数模板本质-学习入门
template<typename T> void mySwap(T &a, T &b) { T c; c = a; a = b; b = c; } int main() ...
- AngularJS开发相关配置
安装步骤: 1. Node.js,下载地址:https://nodejs.org/en/ 2. Git 下载地址:https://git-scm.com/download/ 3. Python (需为 ...
- Js中的变量
1.什么是变量? 在JavaScript中,一种可变的量就称为变量.变量是用来临时存储数据的容器.变量是存在内存中. 2.定义变量 使用var关键字来声明变量 如下图: 3.变量名的命名规则 变量名可 ...
- Android SDK Manager国内无法更新的解决方案
万里长城永不倒,千里黄河水滔滔.算了跑题了. 但还是要吐槽这下这个万里长城,感谢 方滨兴 叫兽 给我们净化了互联网,靠!什么&!@#¥ 此处略去一万字. 现在由于GWF,google基本和咱们 ...
- style、currentStyle、getComputedStyle区别介绍
style.currentStyle.getComputedStyle区别介绍 来自:蓝色天空 样式表有三种方式 内嵌样式(inline Style) :是写在Tag里面的,内嵌样式只对所有的Tag有 ...
- dtcms,header显示头像和用户名,QQ互联老不通过的解决方法
http://bbs.dtsoft.net/forum.php?mod=viewthread&tid=1742&extra=page%3D1
- js给数字加三位一逗号间隔的两种方法(面试题)
方法一: <script type= "text/javascript"> //保留三位小数,toLocaleString() 方法可把一个 Number 对象转换 ...
- 用端口映射在Apache中对每个项目分配端口,实现一个端口访问一个网站
映口映射的功能主要就是实际互联网可以访问当前进行映射的电脑,首先我们要进行路由器的端口映射,常见的开放端口有80,21,3389等,80是网站常用端口,21是FTP服务器常用端口,3389是远程桌面连 ...
- 干净的 ef for Oracle appconfg配置
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSec ...
- 浅析 public static void main(String[] args)
最初接触Java程序的时候,老师就教导我们要从下面这句开始学起,据说是约定俗成的,所以直到今天,还是只知道java程序应该这么写,具体为什么这么写,鄙人惭愧. public class ClassNa ...