「JSOI2013」旅行时的困惑
「JSOI2013」旅行时的困惑
由于我们的图不仅是一个 \(\text{DAG}\) 而且在形态上还是一棵树,也就是说我们为了实现节点之间互相可达,就必须把每条边都覆盖一次,因为两个点之间的路径是唯一的。
那么题意就变成了:每次在图上选出一条路径,覆盖上面的边,求最小的路径数使得所有边都被覆盖至少一次。
看到这里我不禁联想起这道题
那么对于这道题我们就让源点 \(S\) 向所有点连上界为 \(+\infty\) ,下界为 \(0\) 的边,所有点向汇点 \(T\) 连边同理,然后原图中的边连成上界为 \(+\infty\) ,下界为 \(1\) 的边,然后跑一个有源汇上下界最小流即可。
由于这题数据范围还是相对有点大的,所以建议把能加的优化都加上。
#include <cstring>
#include <cstdio>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
template < class T > inline T min(T a, T b) { return a < b ? a : b; }
template < class T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while ('0' > c || c > '9') f |= c == '-', c = getchar();
while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
s = f ? -s : s;
}
const int _ = 2e5 + 10, __ = 1e6 + 10, INF = 2147483647;
int tot = 1, head[_]; struct Edge { int v, w, nxt; } edge[__ << 1];
inline void Add_edge(int u, int v, int w) { edge[++tot] = (Edge) { v, w, head[u] }, head[u] = tot; }
inline void link(int u, int v, int w) { Add_edge(u, v, w), Add_edge(v, u, 0); }
int n, s, t, S, T, d[_], dep[_], cur[_];
inline void Link(int u, int v, int l, int r) { link(u, v, r - l), d[u] -= l, d[v] += l; }
inline int bfs() {
static int hd, tl, Q[_];
memset(dep + 1, 0, sizeof (int) * (n + 4));
hd = tl = 0, dep[Q[++tl] = S] = 1;
while (hd < tl) {
int u = Q[++hd];
for (rg int i = head[u]; i; i = edge[i].nxt) {
int v = edge[i].v, w = edge[i].w;
if (dep[v] == 0 && w)
dep[v] = dep[u] + 1, Q[++tl] = v;
}
}
return dep[T] > 0;
}
inline int dfs(int u, int flow) {
if (u == T) return flow;
for (rg int& i = cur[u]; i; i = edge[i].nxt) {
int v = edge[i].v, w = edge[i].w;
if (dep[v] == dep[u] + 1 && w) {
int res = dfs(v, min(flow, w));
if (res) { edge[i].w -= res, edge[i ^ 1].w += res; return res; }
}
}
return 0;
}
inline int Dinic() {
int res = 0;
while (bfs()) {
for (rg int i = 1; i <= n + 4; ++i) cur[i] = head[i];
while (int d = dfs(S, INF)) res += d;
}
return res;
}
int main() {
#ifndef ONLINE_JUDGE
file("cpp");
#endif
read(n), s = n + 1, t = n + 2, S = n + 3, T = n + 4;
for (rg int u, v, i = 1; i < n; ++i) read(u), ++u, read(v), ++v, Link(u, v, 1, INF);
for (rg int i = 1; i <= n; ++i) Link(s, i, 0, INF), Link(i, t, 0, INF);
for (rg int i = 1; i <= n; ++i) {
if (d[i] > 0) link(S, i, d[i]);
if (d[i] < 0) link(i, T, -d[i]);
}
Dinic();
link(t, s, INF);
Dinic();
printf("%d\n", edge[tot].w);
return 0;
}
「JSOI2013」旅行时的困惑的更多相关文章
- 「JSOI2013」贪心的导游
「JSOI2013」贪心的导游 传送门 多次询问区间内%一个数的最大值 我们不妨设这个数为M_sea 值域比较小所以考虑分块维护. 我们观察到对于给定的一个 \(p\) ,函数 \(y = x \% ...
- 「JSOI2013」哈利波特和死亡圣器
「JSOI2013」哈利波特和死亡圣器 传送门 首先二分,这没什么好说的. 然后就成了一个恒成立问题,就是说我们需要满足最坏情况下的需求. 那么显然在最坏情况下伏地魔是不会走回头路的 因为这显然是白给 ...
- 「JSOI2013」侦探jyy
「JSOI2013」侦探jyy 传送门 个人感觉我写的复杂度不够优秀啊,但是好像没有别的办法了... 我们枚举每个点,考虑这个点能不能不发生. 首先我们从这个点开始,在反图上面 \(\text{BFS ...
- 「JSOI2013」游戏中的学问
「JSOI2013」游戏中的学问 传送门 考虑 \(\text{DP}\) 设 \(dp_{i, j}\) 表示将前 \(i\) 个人分成 \(j\) 个集合,并且第 \(i\) 个人在第 \(j\) ...
- 「JSOI2010」旅行
「JSOI2010」旅行 传送门 比较妙的一道 \(\text{DP}\) 题,思维瓶颈应该就是如何确定状态. 首先将边按边权排序. 如果我们用 \(01\) 串来表示 \(m\) 条边是否在路径上, ...
- 「SDOI2014」旅行(信息学奥赛一本通 1564)(洛谷 3313)
题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我 ...
- bzoj 4464 : [Jsoi2013]旅行时的困惑
网络流建图. 从S向每个点连边,从每个点向T连边. 每条树边反向连一条下界为1,上界inf的边. 跑最小流. 注意加当前弧优化. #include<cstdio> #include< ...
- bzoj 4464: [Jsoi2013]旅行时的困惑【贪心】
据说正解是有上下界最小流,但是这种1e5的玩意问什么要跑网络流啊-- 贪心即可,注意一点是可以有多条路径经过一条边-- 以1为根,设d[u][0/1]为u到父亲的边是向下/向上,g记录这个点儿子中不能 ...
- BZOJ 4464 旅行时的困惑 最小流
题面: Waldives 有 N 个小岛.目前的交通系统中包含 N-1 条快艇专线,每条快艇 专线连接两个岛.这 N-1条快艇专线恰好形成了一棵树. 由于特殊的原因,所有N-1条快艇专线都是单向的.这 ...
随机推荐
- python3爬取电影数据
爬取电影票房数据,用于统计建模分析.目标网站为电影票房数据库(http://58921.com/alltime). 基本的爬取静态网站的技术,模拟登陆使用的是最简单的cookies.(这种模拟登陆的方 ...
- layui之表单验证
这篇文章的表单验证我只是随便记录下,望各位看官理解 1.排序 验证 html代码 <div class="layui-form-item"> <label cla ...
- css各类选择器类型和用法
1.ID 选择器(ID selector,IS):使用 # 标识selector,语法格式:#S{...}(S为选择器名).例:id为name的标签会匹配下面的样式 <style> #na ...
- bzoj 3669: [Noi2014]魔法森林 (LCT & kruskal)
这道题呢, 首先按照关键字a排序,然后不断地加边,用lct维护这个过程 具体实现: 先按照关键字a排序,枚举每一条边,判断两点是否已经联通(kruskal 部分)如果联通,就在两点路径间寻找最大的b, ...
- Flink系统配置
Flink 系统配置 Flink 提供了多个配置参数,用于调整Flink的行为与性能,所有参数均在flink-config.yaml 文件中.下面我们介绍一下几个主要配置. Java and Clas ...
- HDU4714 Tree2cycle 解题报告
题意 给定一棵无根树,删除或连接一条边的代价为\(1\),求把树变为环的最小代价. 前置思路 如果删除了\(k\)条边,使得树变成\((k+1)\)条链,再用\((k+1)\)次连接操作把树变成一个环 ...
- centos 安装mindoc 二进制安装
自建 文档管理系统或者说 wiki系统 mindoc官网: https://www.iminho.me/#%E6%BC%94%E7%A4%BA mindoc github页面:https://gith ...
- 【C 语言】一元二次方程
求一元二次方程:ax2+bx+c=0 的根. 输入三个实数a,b,c的值,且a不等于0. 数学基础:一元二次方程 只含有一个未知数(一元),并且未知数项的最高次数是2(二次)的整式方程叫做一元二次方程 ...
- Python学习(学习视频b站小甲鱼)
001讲 0. Python 是什么类型的语言? Python是脚本语言以简单的方式快速完成某些复杂的事情通常是创造脚本语言的重要原则. 特性: 语法和结构通常比较简单 学习和使用通常比较简单 通常以 ...
- Qt那点事儿(一)
原文http://www.cnblogs.com/andreitang/archive/2011/08/03/2125815.html 第一回 Signal和Slot是同步的还是异步的? 我们知道Qt ...