cf555e(缩点)

给一个 n 个点 m 条边的图,以及 q 对点 (s,t),让你给 m 条边定向。问是否存在一种方案,使每对点的 s 能走到 t。 \(n,m,q≤ 2×10^5\).

首先,在一个边双内,一定存在一种定向方案,使得边双内点两两可达。(考虑桥)

因此,可以直接把边双缩点。然后树上差分看看有没有冲突即可。

注意rmq-st求lca用的是欧拉序!

#include <cstdio>
#include <functional>
#include <algorithm>
using namespace std; typedef pair<int, int> pi;
#define mp make_pair
const int maxn=2e5+5;
int n, m, q; struct Edge{
int fr, to, nxt;
}e1[maxn*2], e2[maxn*2];
int fir1[maxn], fir2[maxn], cnte1=1, cnte2=0;
void addedge(int x, int y, Edge *e, int *fir, int &cnte){
Edge &ed=e[++cnte]; ed.fr=x;
ed.to=y; ed.nxt=fir[x]; fir[x]=cnte; } int tim, dfn[maxn], low[maxn], st[maxn], tl, cntgp, gp[maxn];
void tarjan(int u, int pe, Edge *e, int *fir){ int v;
dfn[u]=low[u]=++tim; st[++tl]=u;
for (int i=fir[u]; i; i=e[i].nxt){
v=e[i].to; if (i==pe) continue; //对于求桥只能保存父边
if (dfn[v]){ low[u]=min(low[u], dfn[v]); continue; }
tarjan(v, i^1, e, fir); low[u]=min(low[u], low[v]);
}
if (dfn[u]!=low[u]) return;
++cntgp;
while (dfn[st[tl]]!=low[st[tl]]) gp[st[tl--]]=cntgp;
gp[st[tl--]]=cntgp;
} int block[maxn], cntb, dep[maxn], ftim[maxn], f[maxn*2][19], rt[maxn];
void st_dfs(int u, int p, Edge *e, int *fir){ int v;
block[u]=cntb; dep[u]=dep[p]+1; ftim[u]=++tim; f[tim][0]=u;
for (int i=fir[u]; i; i=e[i].nxt){
v=e[i].to; if (v==p) continue;
st_dfs(v, u, e, fir);
f[++tim][0]=u; //必须放在这里!!至于为什么,想想菊花(树)
}
} int up[maxn], down[maxn]; //标记类型:立即生效,而不是处理后生效 int getlca(int x, int y){ //注意如果x>y要swap
x=ftim[x]; y=ftim[y];
if (x>y) swap(x, y); int c=-1;
for (int l=y-x+1; l; l>>=1) ++c;
if (dep[f[x][c]]<dep[f[y-(1<<c)+1][c]]) return f[x][c];
else return f[y-(1<<c)+1][c];
} bool ans=true;
pi dfs(int u, int p, Edge *e, int *fir){
pi upi=mp(up[u], down[u]), tmp;
for (int i=fir[u]; i; i=e[i].nxt){
if (e[i].to==p) continue;
tmp=dfs(e[i].to, u, e, fir);
upi.first+=tmp.first; upi.second+=tmp.second;
}
if (upi.first&&upi.second) ans=false;
return upi;
} int main(){
scanf("%d%d%d", &n, &m, &q); int x, y, lca;
for (int i=1; i<=m; ++i){
scanf("%d%d", &x, &y);
addedge(x, y, e1, fir1, cnte1);
addedge(y, x, e1, fir1, cnte1); }
for (int i=1; i<=n; ++i) if (!dfn[i]) tarjan(i, 0, e1, fir1);
int g1, g2; tim=0;
for (int i=2; i<=cnte1; ++i)
if ((g1=gp[e1[i].fr])!=(g2=gp[e1[i].to]))
addedge(g1, g2, e2, fir2, cnte2);
for (int i=1; i<=cntgp; ++i)
if (!dep[i]) ++cntb, rt[i]=1, st_dfs(i, 0, e2, fir2);
for (int i=1; i<19; ++i)
for (int j=1; j<=tim; ++j){
if (j+(1<<i-1)>tim){ f[j][i]=f[j][i-1]; continue; }
if (dep[f[j][i-1]]<dep[f[j+(1<<i-1)][i-1]])
f[j][i]=f[j][i-1]; else f[j][i]=f[j+(1<<i-1)][i-1];
}
for (int i=1; i<=q; ++i){
scanf("%d%d", &x, &y); x=gp[x]; y=gp[y]; lca=getlca(x, y);
if (block[x]!=block[y]){ puts("No"); return 0; }
up[x]+=1; up[lca]+=-1; down[y]+=1; down[lca]+=-1;
}
for (int i=1; i<=cntgp; ++i)
if (rt[i]) dfs(i, 0, e2, fir2);
puts(ans?"Yes":"No");
return 0;
}

cf555e的更多相关文章

  1. CF555E Case of Computer Network

    题面:https://www.luogu.com.cn/problem/CF555E 题意:给定一张\(n\)个点\(m\)条边的无向图. 给定\(q\)组有向点对\((s,t)\). 询问是否存在使 ...

  2. 「CF555E」 Case of Computer Network

    「CF555E」 Case of Computer Network 传送门 又是给边定向的题目(马上想到欧拉回路) 然而这个题没有对度数的限制,你想歪了. 然后又开始想一个类似于匈牙利的算法:我先跑, ...

  3. 题解 CF555E Case of Computer Network

    题目传送门 题目大意 给出一个\(n\)个点\(m\)条边的无向图,有\(q\)次有向点对\((s,t)\),问是否存在一种方法定向每条边使得每个点对可以\(s\to t\). \(n,m,q\le ...

  4. IOI 2020 集训队作业胡扯

    首先安慰自己:做的没集训队快很正常-- 很正常-- 做不完也很正常-- 很正常-- 全都不会做也很正常-- 很正常-- 表格 试题一 完成情况 试题二 完成情况 试题三 完成情况 cf549E cf6 ...

  5. IOI2020只因训队作业胡做

    w a r n i n g ! 意 识 流 警 告 !!1 不想一个个发了,干脆直接发个合集得了qwq 感觉这辈子都做不完了\(Q\omega Q\) CF516D 写过题解了 CF505E 写过题解 ...

  6. IOI 2020 国家集训队作业

    \(\checkmark\) 试题一 完成情况 试题二 完成情况 试题三 完成情况 cf549E cf674G arc103_f \(\checkmark\) cf594E agc034_f agc0 ...

随机推荐

  1. leetcode682

    class Solution { public: int calPoints(vector<string>& ops) { stack<int> ST; ; for ( ...

  2. IDE 文件查找快捷键被占

    快捷键 Ctrl+Shift+F 被搜狗输入法抢占了. 打开搜狗输入法里的快捷键设置,去掉,my ide is ok!

  3. ffmpeg码率控制

    一.VBR与CBR的含义和区别 VBR是动态码率.CBR是静态码率. VBR(Variable Bitrate)动态比特率.也就是没有固定的比特率,压缩软件在压缩时根据音频数据即时确定使用什么比特率, ...

  4. 最长上升子序列(LIS)

    最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS.排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了. 假设存在一个序列d[1..9] = ...

  5. WordPress,discuz 根据不同的入口url更换logo

    Discuz!中调用cookie的思路出来了:    设置cookie:dsetcookie('cookie名', 'cookie值', '有效时间'); 读取cookie有两种方法,第一种使用get ...

  6. 【总结整理】如何判断伪需求(摘自pmcafe)

    1.客户不会直接提需求,都是给解决方案,所以得到用户的反馈之后,先反推一下是很必要的,为什么客户会有这样的方案 总结:方案不合适 例如:客户只会说我要快马,反推一下,其实客户是想要更快,这样的话,解决 ...

  7. 面试题:String StringBufere StringBuilder 不用看

    一.String 使用 private final char value[]来实现字符串存储 所以String对象创建之后就不能再修改此对象中存储的字符串内容,所以说String本质是字符数组char ...

  8. Servlet和JSP简述

    什么是Servlet和JSP 用Java开发Web应用程序时用到的技术主要有两种,即Servlet和JSP. Servlet是在服务器端执行的Java程序,一个被称为Servlet容器的程序(其实就是 ...

  9. 数字图像处理实验(8):PROJECT 04-04,Highpass Filtering Using a Lowpass Image 标签: 图像处理MATLAB 2017-05-25 0

    实验要求: 高通滤波器可以通过1减去低通滤波器的传递函数得到. 使用公式 计算可以的得到 . 实验代码: % PROJECT 04-04 Highpass Filtering Using a Lowp ...

  10. 简单的Cookie记录浏览记录案例

    books.jsp 界面 代码 <%@ page contentType="text/html;charset=UTF-8" language="java" ...