话说,我今天发现我已经一年没发博客了……
算了,开始今天的题目
题目描述
每天早晨,FJ从家中穿过农场走到牛棚。农场由 N 块农田组成,农田通过 M 条双向道路连接,每条路有一定长度。FJ 的房子在 1 号田,牛棚在 N 号田。没有两块田被多条道路连接,以适当的路径顺序总是能在农场任意一对田间行走。当FJ从一块田走到另一块时,总是以总路长最短的道路顺序来走。
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 7 2 1 5 1 3 1 3 2 8 3 5 7 3 4 3 2 4 7 4 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。
【耗时限制】1000ms 【内存限制】128MB
思路:
这道题为了得到更大的最短距离,就一定要改变当前最短路径上的边
那么就用dijkstra算法求出最短距离并求出最大值与第一次的最短路相减,就可以求出答案
思路有了,直接上代码
#include <bits/stdc++.h>
using namespace std;
int n,m,g[105][105],vis[105],dis[105],pre[105];
void djs(int u)
{
memset(vis,0,sizeof(vis));
memset(pre,0,sizeof(pre));
memset(dis,0x3f,sizeof(dis));
dis[u]=0;
for(int i=1;i<=n;i++)
{
int minn=0x3f3f3f3f,v;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&dis[j]<minn)
{
minn=dis[j];
v=j;
}
}
vis[v]=1;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&dis[v]+g[v][j]<dis[j])
{
dis[j]=dis[v]+g[v][j];
pre[j]=v;
}
}
}
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int u,v,w;
cin>>n>>m;
memset(g,0x3f,sizeof(g));
while(m--)
{
cin>>u>>v>>w;
g[u][v]=w;
g[v][u]=w;
}
djs(1);
int d=dis[n],t=n,s=pre[n],maxn=0;
while(s)
{
g[s][t]=g[t][s]=g[s][t]*2;
djs(1);
maxn=max(maxn,dis[n]);
g[s][t]=g[t][s]=g[s][t]/2;
t=s;
s=pre[s];
}
cout<<maxn-d;
return 0;
}
希望对您有帮助,谢谢