一个变形的最短路问题 我们可以在每次寻找最短路的时候都去维护一个当前的最小花费 当我们知道当前找的这条边不是被摧毁的边的时候 我们则需要在pay[edge[i].to]和pay[u]中找一个较小的而不用再考虑这条边的长度
用的刚学的堆优化dijkstra
代码如下
#include<iostream>
#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<string>
using namespace std;
#define in = read()
typedef long long ll;
const ll size = 500000 + 10000;
const ll size2 = 1000 + 10;
struct point{ ll next,to,dis;}edge[size];
priority_queue <pair<ll , ll> , vector<pair<ll , ll> > , greater<pair<ll , ll> > > q;
ll n,m,d,Beginn,Endd;
ll site;
ll head[size],dis[size],pay[size];
bool exist[size],need[size2][size2];
inline ll read(){
ll num = 0 , f = 1; char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') f = -1;
ch = getchar();
}
while(isdigit(ch)){
num = num*10 + ch - '0';
ch = getchar();
}
return num*f;
}
inline void add(ll x, ll y, ll z){
edge[++site].next = head[x];
edge[site].to = y;
edge[site].dis = z;
head[x] = site;
}
int main(){
n in; m in;
for(int i=1;i<=m;i++){
ll x,y,z; x in; y in; z in;
add(x,y,z); add(y,x,z);
}
d in;
for(int i=1;i<=d;i++){
ll x,y; x in; y in;
need[x][y] = need[y][x] = true;
}
Beginn in; Endd in;
memset(dis,127/3,sizeof(dis)); dis[Beginn] = 0;
memset(pay,127/3,sizeof(pay)); pay[Beginn] = 0;
pair<ll , ll> x;
q.push(make_pair(0,Beginn));
while(!q.empty()){
x = q.top(); q.pop(); ll u = x.second;
if(exist[u]) continue;
exist[u] = true;
for(int i=head[u];i!=0;i=edge[i].next)
if(edge[i].dis + dis[u] < dis[edge[i].to]){
dis[edge[i].to] = edge[i].dis + dis[u];
if(need[u][edge[i].to])
pay[edge[i].to] = min(pay[edge[i].to],edge[i].dis + pay[u]);
else
pay[edge[i].to] = min(pay[edge[i].to],pay[u]);
q.push(make_pair(dis[edge[i].to],edge[i].to));
}
exist[u] = false;
}
printf("%d",pay[Endd]);
}
//COYG