题意:给无向图每一条边定向,使得每个点可达点数$R_i$最小值尽可能大,求方案。


条件反射想到二分答案,然后看怎么检验,发现要让所有点$R_i$大于等于某一个值,首先我们关注某些特殊的子图:如果有环的话,显然可以让他定向后各点互达,并且这样的定向并不会影响其他点的$R$。进一步看,如果一个子图,定向后成了一个SCC,显然每个点都可以到达所有子图内的点,显然是很好的。而SCC对应在无向图中,是一个边双,并且因为边双可以看成是一堆环互相套和交组成的连通图,相当于每个环都定一下向,所以显然直接dfs,走过的边方向就是定下的方向,这样就是一个SCC了,可以画图感性理解。。。然后就直接跑边双就行了,缩点之后,成了一棵树,然后树边都是桥,定向的话最后肯定会有至少一个点没有出度,也就是他没有可以走到的点了,那么不妨直接以最大的这个点为无出度点,看他有没有超过mid,再然后发现并不需要二分答案,所以就直接求了。

上述思路有点乱,因为我这题很迷,昨晚没翻题解切掉了,结果今天不会做了。。所以上面这段文字是我今日口胡。。。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define mst(x) memset(x,0,sizeof x)
#define dbg(x) cerr << #x << " = " << x <<endl
#define dbg2(x,y) cerr<< #x <<" = "<< x <<" "<< #y <<" = "<< y <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=4e5+;
struct thxorz{
int to[N<<],head[N],nxt[N<<],tot;
thxorz(){tot=;}
inline void add(int x,int y){
to[++tot]=y,nxt[tot]=head[x],head[x]=tot;
to[++tot]=x,nxt[tot]=head[y],head[y]=tot;
}
}G1,G2;
struct stothx{
int u,v,d;
stothx(int u=,int v=,int d=-):u(u),v(v),d(d){}
}e[N];
int id[N<<];
int n,m,dcc;
#define y G1.to[j]
int dfn[N],low[N],tim,cut[N<<],bel[N],sum[N];
void tarjan(int x,int l){
dfn[x]=low[x]=++tim;
for(register int j=G1.head[x];j;j=G1.nxt[j])if(j^(l^)){
if(!dfn[y]){
tarjan(y,j);MIN(low[x],low[y]);
if(low[y]>dfn[x])cut[j]=cut[j^]=;
}
else MIN(low[x],dfn[y]);
}
}
void dfs(int x){
bel[x]=dcc;++sum[dcc];//dbg2(x,dcc);
for(register int j=G1.head[x];j;j=G1.nxt[j])if(!cut[j]){
if(e[j>>].d==-)x^e[j>>].u?e[j>>].d=:e[j>>].d=;
if(!bel[y])dfs(y);
}
}
#undef y
#define y G2.to[j]
void dfs2(int x,int fa){
for(register int j=G2.head[x];j;j=G2.nxt[j])if(y^fa)dfs2(y,x),bel[e[id[j]].u]^x?e[id[j]].d=:e[id[j]].d=;
}
#undef y
int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
read(n),read(m);
for(register int i=,x,y;i<=m;++i){
read(x),read(y);
G1.add(x,y);
e[i].u=x,e[i].v=y;
}
for(register int i=;i<=n;++i)if(!dfn[i])tarjan(i,);
for(register int i=;i<=n;++i)if(!bel[i])++dcc,dfs(i);
for(register int i=,x,y;i<=m;++i){//m --- n -_-
x=e[i].u,y=e[i].v;//dbg2(x,y),dbg2(bel[x],bel[y]);
if(bel[x]^bel[y])G2.add(bel[x],bel[y]),id[G2.tot]=id[G2.tot-]=i;
}
int tmp=,rt;
for(register int i=;i<=dcc;++i)if(MAX(tmp,sum[i]))rt=i;dbg2(tmp,rt);
dfs2(rt,);
printf("%d\n",tmp);
for(register int i=;i<=m;++i)e[i].d?printf("%d %d\n",e[i].v,e[i].u):printf("%d %d\n",e[i].u,e[i].v);
return ;
}

总结:总结啥啊。。

CF732F Tourist Reform[边双缩点]的更多相关文章

  1. CF732 F Tourist Reform——边双连通分量

    题目:http://codeforces.com/contest/732/problem/F 首先把边双缩点,边双内部 dfs 一个顺序一定是可以从每个点走到边双内部所有点的,因为它是以环为基本单位: ...

  2. CF732F Tourist Reform(边双联通)

    题意 在一张有向图中,设 ri 为从点 i 出发能够到达的点的数量. 定义有向图的“改良值”为 ri 的最小值. 现给出一张无向图,要求给每条边定一个方向,使产生的有向图“改良值”最大. 输出 最大改 ...

  3. codeforces 700C Break Up 暴力枚举边+边双缩点(有重边)

    题意:n个点,m条无向边,每个边有权值,给你 s 和 t,问你至多删除两条边,让s,t不连通,问方案的权值和最小为多少,并且输出删的边 分析:n<=1000,m是30000  s,t有4种情况( ...

  4. POJ3694 Network 边双缩点+LCA+并查集

    辣鸡错误:把dfs和ldfs搞混...QAQ 题意:给定一个无向图,然后查询q次,求每次查询就在图上增加一条边,求剩余割边的个数. 先把边双缩点,然后预处理出LCA的倍增数组: 然后加边时,从u往上跳 ...

  5. ZOJ 4097 Rescue the Princess 边双缩点+LCA

    给你一个图和三个点U,V,W  问你是否存在从U到V和从U到W的两条边不相交路径 先边双缩点 再每个连通分量搞LCA 最后LCA判 #include<bits/stdc++.h> usin ...

  6. C++边双缩点,Redundant Paths 分离的路径

    一道比较简单的 关于边双的题,个人感觉难度不大. 求出整个图的边双,根据边双的定义我们可以延伸出 边双的任两个点都有至少两种路径来互相抵达(因为其不存在割边) .不妨将每个边双缩成一个点,样例中的图便 ...

  7. 732F Tourist Reform

    // CF 732F Tourist Reform // 思路:两遍tarjan // 找强联通分量 #include <bits/stdc++.h> using namespace st ...

  8. Codeforces 732F. Tourist Reform (Tarjan缩点)

    题目链接:http://codeforces.com/problemset/problem/732/F 题意: 给出一个有n个点m条边的无向图,保证联通,现在要求将所有边给定一个方向使其变成有向图,设 ...

  9. HDU5739 Fantasia 树形dp + 点双缩点

    这个题当时打多校的时候有思路,但是代码能力差,没有写出来 事后看zimpha巨巨的题解,看了觉得基本差不多 核心思路:就是找出割点,然后变成森林,然后树形dp就可以搞了 关键就在重新构图上,缩完点以后 ...

随机推荐

  1. cenos 防火墙操作

    iptables防火墙 1.基本操作 # 查看防火墙状态 service iptables status   # 停止防火墙 service iptables stop   # 启动防火墙 servi ...

  2. textarea文本域轻松实现高度自适应

    转载:http://www.xuanfengge.com/textarea-on-how-to-achieve-a-high-degree-of-adaptive.html 今天需要些一个回复评论的页 ...

  3. oracle索引2

    问什么问题? 索引有什么代价?哪些场景下你需要建索引?或者有时候反过来问,哪些场景下不推荐建索引. 建好索引之后,怎么才能最高效地利用索引?或者反过来问,请说出一个无法有效利用已建索引的案例. 索引的 ...

  4. oracle共享数据库操作

    Hello,大家好,这个功能相信新手小白很需要,今天小编因为刚好遇到,所以写出来分享给大家,首先你电脑得有数据库,以及PLSQL工具包,这个相信大家都有了 1.打开NET Manger应用,win10 ...

  5. Android试题

    1. Binder:例子: https://blog.csdn.net/qq_33208587/article/details/82767720

  6. 用python库openpyxl操作excel,从源excel表中提取信息复制到目标excel表中

    现代生活中,我们很难不与excel表打交道,excel表有着易学易用的优点,只是当表中数据量很大,我们又需要从其他表册中复制粘贴一些数据(比如身份证号)的时候,我们会越来越倦怠,毕竟我们不是机器,没法 ...

  7. django中的缓存 跨域问题(同源策略)

    django缓存机制 在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面. 当一个网站的用户访问量很大的时候,每一次的的后台操作 ...

  8. PHP获取指定时间的前6个月月份 、获取前6天日期

    //获取前6个月月份 public function to_sex_month(){ $today = input('param.today') ? input('param.today') : da ...

  9. Spring HttpServletRequest对象的获取

    1.Controller方法上获取 @RequestMapping(value = "/aliyun/ccc/callComing", method = RequestMethod ...

  10. WebStorm使用码云插件问题

    由于项目需求,需要在WebStorm中使用码云插件,在下载安装的过程中出现一系列的问题,现总结出现的问题和解决方法. 先说一下码云是什么?码云有什么作用? 码云的主要功能: 码云除了提供最基础的 Gi ...