正题
题目链接:https://jzoj.net/senior/#contest/show/3005/0
题目大意
nnn个点mmm条边的无向图,有一条边的边权会变化,qqq次变化,每次询问最短路。
解题思路
可变边(x,y)(x,y)(x,y)
路径无非就三种
- 1−>n1->n1−>n
- 1−>x−>y−>n1->x->y->n1−>x−>y−>n
- 1−>y−>x−>n1->y->x->n1−>y−>x−>n
111和nnn都跑一次最短路就好了。
codecodecode
#pragma GCC optimize(2)
%:pragma GCC optimize(3)
%:pragma GCC optimize("Ofast")
%:pragma GCC optimize("inline")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cctype>
#define ll long long
using namespace std;
const ll N=5e5+10;
struct edge_node{ll to,next,w;
}a[N*2];
struct node{ll pos,dis;
};
bool operator<(node x,node y)
{return x.dis>y.dis;}
ll read() {ll x=0,f=1; char c=getchar();while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();return x*f;
}
ll n,m,Q,f1[N],f2[N],ls[N],s,t,tot;
bool v[N];
priority_queue<node> q;
void addl(ll x,ll y,ll w){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=w;return;
}
void dij(ll s,ll *f){memset(v,0,sizeof(v));q.push((node){s,0});f[s]=0;while(!q.empty()){ll x=q.top().pos;q.pop();if(v[x]) continue;v[x]=1;for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(f[x]+a[i].w<f[y]){f[y]=f[x]+a[i].w;if(!v[y])q.push((node){y,f[y]});}}}return;
}
int main()
{freopen("monogatari.in","r",stdin);freopen("monogatari.out","w",stdout);n=read();m=read();Q=read();for(int i=1;i<=n;i++)f1[i]=f2[i]=1e18;for(ll i=1;i<m;i++){ll x=read(),y=read(),w=read();addl(x,y,w);addl(y,x,w);}dij(1,f1);dij(n,f2);s=read();t=read();while(Q--){ll w=read(),ans=f1[n];ans=min(min(f1[s]+f2[t]+w,f1[t]+f2[s]+w),ans);if(ans>=1e18) printf("+Inf\n");else printf("%lld\n",ans);}
}