Roadblock

来源:互联网 发布:中国农大网络教育首页 编辑:程序博客网 时间:2024/06/05 17:47

题目描述

每天早晨,FJ从家中穿过农场走到牛棚。农场由 N 块农田组成,农田通过 M 条双向道路连接,每条路有一定长度。FJ 的房子在 1 号田,牛棚在 N 号田。没有两块田被多条道路连接,以适当的路径顺序总是能在农场任意一对田间行走。当FZ从一块田走到另一块时,总是以总路长最短的道路顺序来走。
FJ 的牛呢,总是不安好心,决定干扰他每天早晨的计划。它们在 M 条路的某一条上安放一叠稻草堆,使这条路的长度加倍。牛希望选择一条路干扰使得FJ 从家到牛棚的路长增加最多。它们请你设计并告诉它们最大增量是多少。

输入输出格式

输入格式:

第 1 行:两个整数 N, M。
第 2 到 M+1 行:第 i+1 行包含三个整数 A_i, B_i, L_i,A_i 和 B_i 表示道路 i 连接的田的编号,L_i 表示路长。

输出格式:

第 1 行:一个整数,表示通过使某条路加倍而得到的最大增量。

输入输出样例

输入样例#1:

5 72 1 51 3 13 2 83 5 73 4 32 4 74 5 2

输出样例#1:

2

说明

【样例说明】

若使 3 和 4 之间的道路长加倍,最短路将由 1-3-4-5 变为 1-3-5。

【数据规模和约定】

对于 30%的数据,N <= 70,M <= 1,500。
对于 100%的数据,1 <= N <= 100,1 <= M <= 5,000,1 <= L_i <= 1,000,000。
只加长一条边,那么只能是加长当前最短路径上的边,枚举即可,因为数据范围很小,代码实现的很蠢Orz。
代码如下

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int size = 200010;int n,m;int tot = 1;int head[size],next[size],dist[size];struct dc{    int t,d;}l[size];int par[size];queue < int > q;void build(int f,int t,int d){    l[tot].t = t;    l[tot].d = d;    next[tot] = head[f];    head[f] = tot ++;}bool use[size];void spfa(int s){    for(int i = 1 ; i <= n ; i ++)        dist[i] = 2147483641;    dist[s] = 0;    use[s] = 1;    q.push(s);    while(!q.empty())    {        int f = q.front();        q.pop();        use[f] = 0;        for(int i = head[f] ; i ; i = next[i])        {            int t = l[i].t;            if(dist[t] > dist[f] + l[i].d)            {                dist[t] = dist[f] + l[i].d;                par[t] = f;                if(!use[t])                {                    use[t] = 1;                    q.push(t);                }            }        }    }}int num[size];int len;void dfs(int u){    num[++len] = u;    if(par[u])        dfs(par[u]);}int main(){    scanf("%d%d",&n,&m);    for(int i = 1 ; i <= m ; i ++)    {        int f,t,d;        scanf("%d%d%d",&f,&t,&d);        build(f,t,d);        build(t,f,d);    }    spfa(1);    int h_ans = dist[n];    dfs(n);    int ans = 0;    for(int i = 1 ; i <= len ; i ++)    {        int pos;        for(int j = head[num[i]] ; j ; j = next[j])            if(l[j].t == num[i+1])                l[j].d = 2 * l[j].d;        for(int j = head[num[i+1]] ; j ; j = next[j])            if(l[j].t == num[i])                l[j].d = 2 * l[j].d;        spfa(1);        ans = max(ans,dist[n] - h_ans);        for(int j = head[num[i]] ; j ; j = next[j])            if(l[j].t == num[i+1])                l[j].d >>= 1;        for(int j = head[num[i+1]] ; j ; j = next[j])            if(l[j].t == num[i])                l[j].d >>= 1;    }    printf("%d\n",ans);    return 0;}

传送门:https://www.luogu.org/problem/show?pid=2176

0 0