[洛谷P2176] [USACO14FEB] 路障Roadblock

Description

给定一张无向图,FJ在1号点,牛棚在n号点

FJ每次去牛棚都会按照最短路顺序(只走最短路)奶牛们可以让任意一条最短路上的边扩大2倍 此时就会出现一个比最短路更大的路的权值 即为增值

问 最大增值???

Solution

先跑一边dijkstra求出最短路 记录最短路权值为d  在求最短路的同时记录最短路的边 可以设一个数组pre,pre[i]表示i点是从哪个点转移过来的

另一个数组bian,bian[i] 表示从上一个点过来的边的编号

另开一个数组 记录最短路边的编号  枚举每个最短路的边 扩大2倍 再跑一遍dijkstra求出最短路权值 在每次中找到最大的权值ans

最后用ans - d即可 

附:

至于边的修改 我们把边从2开始存 求另一个只需要^1 至于为啥我也不知道 

Code

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <queue>
 4 #include <cstring>
 5 #define pa pair<int, int>
 6 using namespace std;
 7 int n, m, num = 1;
 8 int head[150000], dis[1200], vis[1200], pre[1200], bian[120];
 9 priority_queue<pa, vector<pa>, greater<pa> >q;
10 int b[1200];
11 struct emmm
12 {
13     int next, to, dis;
14 }e[150000];
15 void add (int from, int to, int dis) {
16     e[++num].next = head[from];
17     e[num].to = to;
18     e[num].dis = dis;
19     head[from] = num;
20 }
21 void dijkstra() {
22     memset(dis, 0x3f3f3f, sizeof(dis));
23     memset(vis, 0, sizeof(vis));
24     dis[1] = 0;
25     q.push(make_pair(0, 1));
26     while (!q.empty()) {
27         int now = q.top().second;
28         q.pop();
29         if (vis[now]) continue;
30         vis[now] = 1;
31         for (int i = head[now];i;i = e[i].next) {
32             int v = e[i].to;
33             if (dis[v] > dis[now] + e[i].dis) {
34                 dis[v] = dis[now] + e[i].dis;
35                 pre[v] = now;
36                 bian[v] = i;
37                 q.push(make_pair(dis[v], v));
38             }
39         }
40     }
41 }
42 int main() {
43     ios::sync_with_stdio(false);
44     cin >> n >> m;
45     int x, y, z;
46     for (int i = 1;i <= m; i++) {
47         cin >> x >> y >> z;
48         add(x, y, z);
49         add(y, x, z);
50     }
51     dijkstra();
52     int now1 = n, sum = 0, ans = dis[n], kkk = 0;
53     while (now1 != 1) {
54         b[++sum] = bian[now1];
55         now1 = pre[now1];
56     }
57     for (int i = 1;i <= sum; i++) {
58         e[b[i]].dis<<=1;
59         e[b[i]^1].dis<<=1;
60         dijkstra();
61         kkk = max(kkk, dis[n]);
62         e[b[i]].dis>>=1;
63         e[b[i]^1].dis>>=1;
64     }
65     cout << kkk - ans << endl;
66     return 0;
67 }
AC Code

 

转载于:https://www.cnblogs.com/-sheldon/p/11379206.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值