Description

可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校。直到有一天他们两人参加了学校的信息学奥林匹克竞赛小组才发现每天上学的乘车路线不一定是最优的。 可可:“很可能我们在上学的路途上浪费了大量的时间,让我们写一个程序来计算上学需要的最少时间吧!” 合肥市一共设有N个公交车站,不妨将它们编号为1…N的自然数,并认为可可和卡卡家住在1号汽车站附近,而他们学校在N号汽车站。市内有M条直达汽车路线,执行第i条路线的公交车往返于站点pi和qi之间,从起点到终点需要花费的时间为ti。(1<=i<=M, 1<=pi, qi<=N) 两个人坐在电脑前,根据上面的信息很快就编程算出了最优的乘车方案。然而可可忽然有了一个鬼点子,他想趁卡卡不备,在卡卡的输入数据中删去一些路线,从而让卡卡的程序得出的答案大于实际的最短时间。而对于每一条路线i事实上都有一个代价ci:删去路线的ci越大卡卡就越容易发现这个玩笑,可可想知道什么样的删除方案可以达到他的目的而让被删除的公交车路线ci之和最小。 [任务] 编写一个程序:  从输入文件中读取合肥市公交路线的信息;  计算出实际上可可和卡卡上学需要花费的最少时间;  帮助可可设计一个方案,删除输入信息中的一些公交路线,使得删除后从家到学校需要的最少时间变大,而被删除路线的ci和最小;向输出文件输出答案。

Input

输入文件中第一行有两个正整数N和M,分别表示合肥市公交车站和公交汽车路线的个数。以下M行,每行(第i行,总第(i+1)行)用四个正整数描述第i条路线:pi, qi, ti, ci;具体含义见上文描述。

Output

输出文件最多有两行。 第一行中仅有一个整数,表示从可可和卡卡家到学校需要的最短时间。 第二行输出一个整数C,表示Ci之和

Sample Input

6 7
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

2
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]上学路线的更多相关文章

  1. bzoj1266 [AHOI2006]上学路线route floyd建出最短路图+最小割

    1266: [AHOI2006]上学路线route Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 2490  Solved: 898[Submit][S ...

  2. bzoj1266 [AHOI2006]上学路线route floyd+最小割

    1266: [AHOI2006]上学路线route Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 2490  Solved: 898[Submit][S ...

  3. BZOJ1266 AHOI2006上学路线(最短路+最小割)

    求出最短路后找出可能在最短路上的边,显然割完边后我们需要让图中这样的边无法构成1到n的路径,最小割即可,非常板子. #include<iostream> #include<cstdi ...

  4. BZOJ1266 [AHOI2006]上学路线route Floyd 最小割 SAP

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1266 题意概括 一个无向图,第一问:从1~n的最短路. 第二问,删除价值总和最小的边,使得1~n的 ...

  5. bzoj1266: [AHOI2006]上学路线route

    最短路+最小割 首先如何使最短路变长?就是要每一条最短路都割一条边. 我们求出每个点到点1和点n的距离,就可以知道哪些边在最短路上(一开始没有想到求到0和n的距离,想用floyd,但是n=500,怕超 ...

  6. 【最短路】【spfa】【最小割】【Dinic】bzoj1266 [AHOI2006]上学路线route

    原问题等价于断掉一些边,让原来所有的最短路全都无法联通S和T. 先求最短路,然后把在最短路上的边(dis[u[i]]+w[i]==dis[v[i]])加入新图里,跑最小割.显然. 注意是无向图. #i ...

  7. 【BZOJ1266】[AHOI2006]上学路线route Floyd+最小割

    [BZOJ1266][AHOI2006]上学路线route Description 可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信息学奥林 ...

  8. BZOJ 1266: [AHOI2006]上学路线route(最短路+最小割)

    第一问最短路.第二问,先把最短路的图建出来(边(u,v)满足d[s->u]+d[v->t]+d(u,v)==最短路径长度,就在图中,可以从源点和汇点分别跑一次最短路得到每个点到源点和汇点的 ...

  9. BZOJ_1266_[AHOI2006]上学路线route_最小割

    BZOJ_1266_[AHOI2006]上学路线route_最小割 Description 可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信 ...

随机推荐

  1. P4383 [八省联考2018]林克卡特树lct

    题目链接 题意分析 一句话题意就是 : 让你选出\((k+1)\)条不相交的链 使得这些链的边权总和最大 (这些链可以是点) 我们考虑使用树形\(DP\) \(dp[i][j][0/1/2]\)表示以 ...

  2. python3.6的request

    request实例1: import requests payload = {'key1':'value','key2':'value2'} url = "http://httpbin.or ...

  3. P3440 [POI2006]SZK-Schools

    传送门 应该是很显然的费用流模型吧... $S$ 向所有学校连边,流量为 $1$,费用为 $0$(表示每个学校要选一个编号) 学校向范围内的数字连边,流量为 $1$,费用为 $c|m-m'|$(表示学 ...

  4. Mac 10.12安装抓包工具Charles

    说明:青花瓷,Filddler之后就是这个最好用.收费软件. 下载: (链接:https://pan.baidu.com/s/1kV1Robl 密码: 3g6u)

  5. hibernate_boolean类型的处理

    xml方式,直接写就行,hibernate会直接帮你生成: javaBean代码片段: private boolean leaf; public boolean isLeaf() { return l ...

  6. linux 打包 压缩 解压缩

    gzip gzip xxx文件 压缩文件xxx,后缀.gz 并且删除原来文件 gzip -tv xxx.gz 测试压缩文件压完整性 压缩当前文件夹所有文件: zip -r ./1.zip ./* -r ...

  7. linux 下 vi 编辑器 使用

    命令模式(command mode).插入模式(Insert mode)和底行模式(last line mode) 1.进入插入模式 按「i」切换进入插入模式「insert mode」,按“i”进入插 ...

  8. ruby gems列表

    https://github.com/shageman/cobradeps

  9. struts2 基本流程

    一.配置过程 1.在web.xml中配置过滤器 <filter> <filter-name>StrutsPrepareAndExecuteFilter</filter-n ...

  10. Django models 的增删改查

    增 from app01.models import * #create方式一: Author.objects.create(name='Alvin') #create方式二: Author.obje ...