洛谷P2176 [USACO14FEB]路障Roadblock
洛谷P2176 [USACO14FEB]路障Roadblock
题目描述
每天早晨,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\) 行:一个整数,表示通过使某条路加倍而得到的最大增量。
思路
为了得到更大的最短距离,就一定要改变当前最短路径上的边
那么就用一个很朴素的方法,枚举当前最短路上的每一条边,增大这条边的长度,然后再求最短路
最后取个最大值就可以求出答案
CODE
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define MAXN 210
#define MAXM 20010
struct Node{
int u,v,w;
Node(){}
Node(int u,int v,int w):u(u),v(v),w(w){}
}p[MAXM];
struct R{
int val,id;
R(){}
R(int val,int id):val(val),id(id){}
bool operator < (const R &a) const{
return val>a.val;
}
}tmp;
int head[MAXN],Next[MAXM],dis[MAXN],pre[MAXN],li[MAXN];
bool vis[MAXN];
int i,j,k,m,n,u,v,w,tot,cnt,ans,dist;
priority_queue<R> mque;
void addNode(int u,int v,int w){
p[++tot]=Node(u,v,w);
Next[tot]=head[u],head[u]=tot;
p[++tot]=Node(v,u,w);
Next[tot]=head[v],head[v]=tot;
}
bool relax(int u,int v,int w){
if(dis[u]+w<dis[v]){
dis[v]=dis[u]+w;
return true;
}
return false;
}
int dijkstra(int src,int goal){
while(!mque.empty()) mque.pop();
for(int i=1;i<=n;i++) dis[i]=1000000000;
memset(vis,0,sizeof(vis));
dis[src]=0;
pre[src]=-1;
mque.push(R(0,src));
while(!mque.empty()){
tmp=mque.top(); mque.pop();
if(vis[tmp.id]) continue;
vis[tmp.id]=true;
for(int i=head[tmp.id];i+1;i=Next[i]){
if(relax(p[i].u,p[i].v,p[i].w)){
pre[p[i].v]=i;
mque.push(R(dis[p[i].v],p[i].v));
}
}
}
return dis[goal];
}
void dfs(int src){
if(src==-1) return;
dfs(pre[p[src].u]);
li[++cnt]=src;
}
int main(){
memset(head,-1,sizeof(head));
tot=-1;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
addNode(u,v,w);
}
dist=dijkstra(1,n);
dfs(pre[n]);
ans=0;
for(i=1;i<=cnt;i++){
p[li[i]].w*=2;
p[li[i]^1].w*=2;
ans=max(ans,dijkstra(1,n));
p[li[i]].w/=2;
p[li[i]^1].w/=2;
}
printf("%d\n",ans-dist);
return 0;
}

浙公网安备 33010602011771号