Codeforces 567E President and Roads (用Dijkstra求最短路条数 + 强连通桥)
来源:互联网 发布:数据库备份类型 编辑:程序博客网 时间:2024/05/08 12:15
@(K ACMer) by 题解工厂
题意:
给你一个有向图,问你这条边是不是最短路必须经过的边.如果不是能不能通过减少它的长度(但必须边的长度大于0)来让它成为必须经过的边.
分析:
先谈,判断一个路径(u, v)是不是最短路上的路.显然如果u到起点的距离加上v到终点的距离,再加上(u,v)边的长度等于起点到终点的最短路长度,那么这个边就可能是最短路上的路,但是不一定就是,因为也可能存在和它等效的边.
那么如何判断最短路必须经过(u,v)这条边否呢?
首先这条边必须是可能的最短路上的路径,这就需要满足长度的关系.
然后只需要满足起点到u的最短路条数a乘以v到终点的最短路条数b等于起点到终点的最短路条数即可.
要完成以上两个关于路径长度和路径数的判断,都需要用dijkstra算法,分别从起点和终点建图,且建图的时候,不只是要有最短路长度,还要有路径数.Dijkstra很天然的可以算出,从起点到该点的最短路条数,只需要看它被相同更新了多少次,没更新一次,就把它前驱节点的条数给它加上.
有了以上的方法,减少多少变为毕竟最短路的也就容易类比想到了.
Dijkstra算法的两个特点:
最短路条数:首先更据上面的内容,Dijstra算法不仅仅可以算最短路长度,还可以算,最短路条数.
任意点到起点最短路:跑了一遍Dijkstra算法之后,会得到一个d[]数组,这是起点到每个点的最短距离.我们可以利用这一特性,可以计算每一个点到起点的最短距离(在无向图中,显然就等于起点到每个点的最短距离,有向图就不同了).方法如下:
以该有向图建立一个反图(反图就是,把有向图中每一个边都反向).然后跑一次Dijkstra,就得到反图中起点到任意点的最短距离,但其实在原图中把这条路径反过来,就是起任意点到起点的最短距离.
Code:
#include <iostream>#include <cstdio>#include <string>#include <algorithm>#include <set>#include <map>#include <vector>#include <queue>#include <iterator>#include <cmath>#include <cstring>#include <cstdlib>using namespace std;typedef long long LL;typedef pair<LL, LL> P;const LL M = 200009;LL INF = 1000000000000LL;LL prime = 1044556773;LL V, E, s, e;struct edges{LL from, to, cost;};struct edge{LL to, cost;};vector<struct edge> G1[M], G2[M];vector<edges > g;struct dot{LL x, ways;}d1[M], d2[M];void input(void){ scanf("%I64d%I64d%I64d%I64d", &V, &E, &s, &e); for (LL i = 0; i < E; i++) { LL x, y, z; scanf("%I64d%I64d%I64d", &x, &y, &z); G1[x].push_back({y, z}); G2[y].push_back({x, z}); g.push_back({x, y, z}); }}void dijkstra1(LL s){ priority_queue<P, vector<P>, greater<P> > que; for (LL i = 0; i < V + 100; i++) d1[i].x = INF, d1[i].ways = 0; d1[s].x = 0; d1[s].ways = 1; que.push(P(0, s)); while (!que.empty()) { P p = que.top(); que.pop(); LL v = p.second; if (d1[v].x < p.first) continue; for (LL i = 0; i < G1[v].size(); i++) { edge ed = G1[v][i]; if (d1[ed.to].x == d1[v].x + ed.cost ) { d1[ed.to].ways = (d1[v].ways % prime + d1[ed.to].ways % prime) % prime; } else if (d1[ed.to].x > d1[v].x + ed.cost){ d1[ed.to].x = d1[v].x + ed.cost; d1[ed.to].ways = d1[v].ways; que.push(P(d1[ed.to].x, ed.to)); } } }}void dijkstra2(LL s){ priority_queue<P, vector<P>, greater<P> > que; for (LL i = V + 100; i > 0; i--) d2[i].x = INF, d2[i].ways = 0; d2[s].x = 0; d2[s].ways = 1; que.push(P(0, s)); while (!que.empty()) { P p = que.top(); que.pop(); LL v = p.second; if (d2[v].x < p.first) continue; for (LL i = 0; i < G2[v].size(); i++) { edge ed = G2[v][i]; if (d2[ed.to].x == d2[v].x + ed.cost) { d2[ed.to].ways = (d2[v].ways % prime + d2[ed.to].ways % prime) % prime; } else if (d2[ed.to].x > d2[v].x + ed.cost){ d2[ed.to].x = d2[v].x + ed.cost; d2[ed.to].ways = d2[v].ways; que.push(P(d2[ed.to].x, ed.to)); } } }}int main(void){ input(); dijkstra1(s); dijkstra2(e); for (LL i = 0; i < g.size(); i++) { LL sx = g[i].from, ex = g[i].to, y = g[i].cost; if (d1[sx].x + d2[ex].x == d1[e].x - y && ((d1[sx].ways%prime) * (d2[ex].ways%prime))%prime == d1[e].ways % prime) { printf("YES\n"); } else { LL z = d1[e].x - d1[sx].x - d2[ex].x; if (z - 1<= 0) printf("NO\n"); else {printf("CAN %I64d\n", y - z + 1);} } } return 0;}
- Codeforces 567E President and Roads (用Dijkstra求最短路条数 + 强连通桥)
- Codeforces Round #Pi (Div. 2) E. President and Roads (最短路+强连通求割边)
- CodeForces 567E President and Roads(最短路 + tarjan求桥)
- CodeForces 567E President and Roads(最短路 + tarjan)
- Codeforces 567E President and Roads (最短路 好题)
- Codeforces 567E President and Roads 【最短路】
- Codeforces E. President and Roads (优先队列Dijkstar + 强连通 找必最短路上的必须边(桥))经典
- Codeforces E. President and Roads (优先队列Dijkstar + 强连通 找必最短路上的必须边(桥))
- CodeForces 567E President and Roads(最短路 + 双联通分量)
- Codeforces Round #Pi (Div. 2) E. President and Roads 最短路,桥
- Codeforces 567 E. President and Roads
- Codeforces 567E President and Roads
- codeforces 567E President and Roads Dijikstra
- Codeforces 567E President and Roads 题解
- Codeforces Round #Pi (Div. 2) E. President and Roads(边双无向图缩点(有重边)+最短路)
- 08/13 D -> codeforces Round #Pi div 2 E. President and Roads 最短路变形
- 最短路+tarjan codeforces567E President and Roads
- eoj1818 dijkstra求最短路及其条数
- Swift UIButton UIButtonType
- android 制作9.png图片
- Go环境搭建
- MSSQL数据库测试连接的快捷方法
- Java获取时间范围: 当前季度,上个季度,昨天,当前月,上个月
- Codeforces 567E President and Roads (用Dijkstra求最短路条数 + 强连通桥)
- HDU 5428 The Factor
- 好好学语文
- Linux字符设备驱动之Tiny6410 LED驱动分析
- 常见笔试题记录
- jsp页面的字段要求:存整数、存二位小数等
- include的使用
- KMP算法
- InputStream InputStreamReader BufferedReader