タイトルの説明
ジョンは毎朝、家から農場まで歩いていかなければならず、途中で他の場所を通過しなければならない場合があります。これらの場所と道路を1つの画像に抽象化します。この画像にはN個のポイントがあり、Mサイド(各サイドは双方向サイド)があり、各サイドには長さがあり、ジョンの家が最初のポイントです。 、ファームはN番目のポイントにあり、2つのポイント間に重複するエッジはなく、このグラフは接続されたグラフです。ジョンは自宅からファームへの最短経路を選択するたびに。
しかし、ジョンの牛は常にジョンをめちゃくちゃにしました。牛は、ジョンの歩行を妨げるために、干し草の山を道路の1つに置くことを計画していました。今、牛はジョンの家から農場への旅を最大にするために、干し草の山を選ぶ方法を知りたがっています。
入力
最初の行は2つの正の整数NとMです。
次のM行では、3つの整数a、b、cは、点aから点bまでの距離がcであることを示しています。
アウトプット
家から農場までの最短経路が最大で増加する距離を出力します。
入力例
5 7
2 1 5
1 3 1
3 2 8
3 5 7
3 4 3
2 4 7
4 5 2
出力例
2
データ範囲の制限
1 <= N <= 250,1 <= M <= 25000。
プロンプト
[説明の例]
牛が3-4の辺に干し草を置くと、3-4の辺の長さが3から6に変わることに相当し、ジョンの最短経路は1-3-5になります。距離は1 + 7 = 8に等しく、元の最短の長さより2長くなります。
分析
この質問は「単一ソースの最短経路」であるため、非常に暴力的であり、SPFAが使用されます。
最初に1〜nの最短経路を見つけ、次に干し草を置く場所として各道路を列挙します。最大の違いは答えです。
コードオン
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,h,t,a[25001],b[25001],c,f[260][260],dis[260],k,ff,mx,v[100010],q[100010];
int spfa()
{
memset(v,0,sizeof(v));
memset(q,0,sizeof(q));
memset(dis,1,sizeof(dis));
int x;
dis[1]=0;
v[1]=1;
q[1]=1;
h=0;
t=1;
while(h<t)
{
h++;
x=q[h];
for(int i=1;i<=n;i++)
{
if(dis[x]+f[x][i]<dis[i]&&f[x][i]!=0)
{
dis[i]=dis[x]+f[x][i];//松弛
if(!v[i])
{
t++;
v[i]=1;
q[t]=i;
}
}
}
v[x]=0;
}
return dis[n];
}
int main()
{
freopen("rblock.in","r",stdin);
freopen("rblock.out","w",stdout);
cin>>n>>m;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a[i],&b[i],&c);
f[a[i]][b[i]]=c;
f[b[i]][a[i]]=c;
}
k=spfa();
for(int i=1;i<=m;i++)
{
f[a[i]][b[i]]*=2;
f[b[i]][a[i]]*=2;
ff=spfa();
f[a[i]][b[i]]/=2;
f[b[i]][a[i]]/=2;
if(ff-k>mx) mx=ff-k;
}
printf("%d",mx);
fclose(stdin);
fclose(stdout);
return 0;
}