BZOJ1266 [AHOI2006]上学路线
Description
Input
Output
Sample Input
1 2 1 3
2 6 1 5
1 3 1 1
3 4 1 1
4 6 1 1
5 6 1 2
1 5 1 4
Sample Output
5
HINT
2<=N<=500, 1<=M<=124 750, 1<=ti, ci<=10 000
合肥市的公交网络十分发达,你可以认为任意两个车站间都可以通过直达或转车互相到达,当然如果在你提供的删除方案中,家和学校无法互相到达,那么则认为上学需要的最短为正无穷大:这显然是一个合法的方案。
题解
首先Dijkstra求出起点到所有点的距离$dis_i$,然后我们发现当前影响最短路长度的边只有$dis_{q_i}=dis_{p_i}+t_i$的边,将保留这些边,求最小割即可。
附代码:
#include <algorithm>
#include <cstdio>
#include <queue>
typedef long long LL;
const LL INF = 1000000000000000LL;
const int N = 550;
const int M = 300000;
int pre[N], nxt[M], to[M], t[M], c[M], cnt = 0;
inline void addedge(int p, int q, int ti, int ci) {
to[cnt] = q; t[cnt] = ti; c[cnt] = ci;
nxt[cnt] = pre[p]; pre[p] = cnt++;
to[cnt] = p; t[cnt] = ti; c[cnt] = ci;
nxt[cnt] = pre[q]; pre[q] = cnt++;
}
LL dis[N];
int n, m;
struct HeapNode{
int x;
LL d;
HeapNode(int x = 0, LL d = 0) : x(x), d(d) {}
inline bool operator<(const HeapNode &y)const{
return d > y.d;
}
};
void Dijkstra() {
static std::priority_queue<HeapNode> Q;
std::fill(dis + 1, dis + n + 1, INF);
while (!Q.empty()) Q.pop();
Q.push(HeapNode(1, dis[1] = 0));
while (!Q.empty()) {
HeapNode x = Q.top(); Q.pop();
if (x.d != dis[x.x]) continue;
int u = x.x;
if (u == n) return;
for (int i = pre[u]; ~i; i = nxt[i])
if (dis[to[i]] > dis[u] + t[i])
Q.push(HeapNode(to[i], dis[to[i]] = dis[u] + t[i]));
}
}
struct Dinic{
int pre[N], nxt[M], to[M], cnt;
LL ret[M];
int dis[N];
Dinic() {
cnt = 0;
std::fill(pre, pre + N, -1);
}
inline void addedge(int p, int q, LL c) {
to[cnt] = q; ret[cnt] = c;
nxt[cnt] = pre[p]; pre[p] = cnt++;
to[cnt] = p; ret[cnt] = 0;
nxt[cnt] = pre[q]; pre[q] = cnt++;
}
bool BFS() {
static std::queue<int> Q;
while (!Q.empty()) Q.pop();
std::fill(dis + 1, dis + n + 1, -1);
dis[1] = 0;
Q.push(1);
while (!Q.empty()) {
int x = Q.front(); Q.pop();
for (int i = pre[x]; ~i; i = nxt[i])
if (ret[i] && !~dis[to[i]]) {
dis[to[i]] = dis[x] + 1;
Q.push(to[i]);
if (to[i] == n) return true;
}
}
return false;
}
LL DFS(int x, LL f) {
if (x == n) return f;
LL ans = 0;
for (int i = pre[x]; ~i && f; i = nxt[i])
if (ret[i] && dis[to[i]] == dis[x] + 1) {
LL df = DFS(to[i], std::min(f - ans, ret[i]));
ans += df;
ret[i] -= df; ret[i ^ 1] += df;
}
if (ans == f) dis[x] = n + 2;
return ans;
}
LL solve() {
LL ans = 0;
while (BFS()) ans += DFS(1, INF);
return ans;
}
};
Dinic solver;
int main() {
scanf("%d%d", &n, &m);
std::fill(pre + 1, pre + n + 1, -1);
int p, q, ti, ci;
for (int i = 0; i < m; ++i) {
scanf("%d%d%d%d", &p, &q, &ti, &ci);
addedge(p, q, ti, ci);
}
Dijkstra();
for (int i = 0; i < cnt; ++i)
if (dis[to[i]] - dis[to[i ^ 1]] == t[i])
solver.addedge(to[i ^ 1], to[i], c[i]);
printf("%lld\n%lld\n", dis[n], solver.solve());
return 0;
}
BZOJ1266 [AHOI2006]上学路线的更多相关文章
- bzoj1266 [AHOI2006]上学路线route floyd建出最短路图+最小割
1266: [AHOI2006]上学路线route Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 2490 Solved: 898[Submit][S ...
- bzoj1266 [AHOI2006]上学路线route floyd+最小割
1266: [AHOI2006]上学路线route Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 2490 Solved: 898[Submit][S ...
- BZOJ1266 AHOI2006上学路线(最短路+最小割)
求出最短路后找出可能在最短路上的边,显然割完边后我们需要让图中这样的边无法构成1到n的路径,最小割即可,非常板子. #include<iostream> #include<cstdi ...
- BZOJ1266 [AHOI2006]上学路线route Floyd 最小割 SAP
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1266 题意概括 一个无向图,第一问:从1~n的最短路. 第二问,删除价值总和最小的边,使得1~n的 ...
- bzoj1266: [AHOI2006]上学路线route
最短路+最小割 首先如何使最短路变长?就是要每一条最短路都割一条边. 我们求出每个点到点1和点n的距离,就可以知道哪些边在最短路上(一开始没有想到求到0和n的距离,想用floyd,但是n=500,怕超 ...
- 【最短路】【spfa】【最小割】【Dinic】bzoj1266 [AHOI2006]上学路线route
原问题等价于断掉一些边,让原来所有的最短路全都无法联通S和T. 先求最短路,然后把在最短路上的边(dis[u[i]]+w[i]==dis[v[i]])加入新图里,跑最小割.显然. 注意是无向图. #i ...
- 【BZOJ1266】[AHOI2006]上学路线route Floyd+最小割
[BZOJ1266][AHOI2006]上学路线route Description 可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信息学奥林 ...
- BZOJ 1266: [AHOI2006]上学路线route(最短路+最小割)
第一问最短路.第二问,先把最短路的图建出来(边(u,v)满足d[s->u]+d[v->t]+d(u,v)==最短路径长度,就在图中,可以从源点和汇点分别跑一次最短路得到每个点到源点和汇点的 ...
- BZOJ_1266_[AHOI2006]上学路线route_最小割
BZOJ_1266_[AHOI2006]上学路线route_最小割 Description 可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信 ...
随机推荐
- P4383 [八省联考2018]林克卡特树lct
题目链接 题意分析 一句话题意就是 : 让你选出\((k+1)\)条不相交的链 使得这些链的边权总和最大 (这些链可以是点) 我们考虑使用树形\(DP\) \(dp[i][j][0/1/2]\)表示以 ...
- python3.6的request
request实例1: import requests payload = {'key1':'value','key2':'value2'} url = "http://httpbin.or ...
- P3440 [POI2006]SZK-Schools
传送门 应该是很显然的费用流模型吧... $S$ 向所有学校连边,流量为 $1$,费用为 $0$(表示每个学校要选一个编号) 学校向范围内的数字连边,流量为 $1$,费用为 $c|m-m'|$(表示学 ...
- Mac 10.12安装抓包工具Charles
说明:青花瓷,Filddler之后就是这个最好用.收费软件. 下载: (链接:https://pan.baidu.com/s/1kV1Robl 密码: 3g6u)
- hibernate_boolean类型的处理
xml方式,直接写就行,hibernate会直接帮你生成: javaBean代码片段: private boolean leaf; public boolean isLeaf() { return l ...
- linux 打包 压缩 解压缩
gzip gzip xxx文件 压缩文件xxx,后缀.gz 并且删除原来文件 gzip -tv xxx.gz 测试压缩文件压完整性 压缩当前文件夹所有文件: zip -r ./1.zip ./* -r ...
- linux 下 vi 编辑器 使用
命令模式(command mode).插入模式(Insert mode)和底行模式(last line mode) 1.进入插入模式 按「i」切换进入插入模式「insert mode」,按“i”进入插 ...
- ruby gems列表
https://github.com/shageman/cobradeps
- struts2 基本流程
一.配置过程 1.在web.xml中配置过滤器 <filter> <filter-name>StrutsPrepareAndExecuteFilter</filter-n ...
- Django models 的增删改查
增 from app01.models import * #create方式一: Author.objects.create(name='Alvin') #create方式二: Author.obje ...