题目描述
因为门卫红美玲的失误,疏忽将入侵者放入了红魔馆。入侵者袭击了红魔馆的大小姐蕾米莉亚·斯卡雷特,大小姐在施放【必杀·斯卡雷特家绝技·抱头蹲防】无效后只好变成了好多蝙蝠,在红魔馆中分散开来。
现在的当务之急是找到二小姐芙兰朵露·斯卡雷特,并且与大小姐化身成的所有蝙蝠集合在一点。你的任务就是帮她们找一条最佳路线。
我们可以用一个无向图来表示红魔馆的地图。蝙蝠和二小姐走过任何一条边都要付出一定的代价。因为形态不同,蝙蝠和二小姐走同一条边付出的代价可能不同。但是如果某一只蝙蝠与二小姐碰面,那么二小姐由于蝙蝠的引导,以后的所有路程可以不支付代价。(也就是相当于二小姐和某只蝙蝠都走到某点,之后无视二小姐的存在。)现在已知所有蝙蝠,二小姐和目标集合点的位置,请你求出所有蝙蝠和二小姐行走代价的和的最小值。
输入文件
第一行是55个正整数,n,m,k,S,Tn,m,k,S,T,分别代表无向图点数,边数,蝙蝠的数量,二小姐所在起点的编号,目标点的编号。
第二行是kk个正整数,分别代表大小姐每个蝙蝠所在的起点的编号。
接下来有mm行,每行有44个正整数,u,v,q,pu,v,q,p,分别是该边的起点、终点,蝙蝠通过该路花费的代价,二小姐通过该路花费的代价。
输出文件
一行,一个整数,所有人物达到终点所需要的代价的和的最小值。
样例
[input]
5 5 2 3 4
1 5
1 2 3 5
3 2 3 5
2 4 4 9
3 4 9 6
5 4 1 1
[output]
13
Extra Input Sample
Extra Output Sample
样例解释
11号蝙蝠从 11 到 22,花费 33
二小姐从 33 到 22,花费 55,遇见蝙蝠,之后不计算费用
11 号蝙蝠从 22 到 44,花费 44
22 号蝙蝠从 55 到 44,花费 11
总计 1313
数据约定
对于 30% 的数据,1≤n≤2001≤n≤200
对于 另外20% 的数据, S=TS=T。
对于 另外20% 的数据, 1≤k≤5,1≤n≤1000,1≤m≤100001≤k≤5,1≤n≤1000,1≤m≤10000。
因为门卫红美玲的失误,疏忽将入侵者放入了红魔馆。入侵者袭击了红魔馆的大小姐蕾米莉亚·斯卡雷特,大小姐在施放【必杀·斯卡雷特家绝技·抱头蹲防】无效后只好变成了好多蝙蝠,在红魔馆中分散开来。
现在的当务之急是找到二小姐芙兰朵露·斯卡雷特,并且与大小姐化身成的所有蝙蝠集合在一点。你的任务就是帮她们找一条最佳路线。
我们可以用一个无向图来表示红魔馆的地图。蝙蝠和二小姐走过任何一条边都要付出一定的代价。因为形态不同,蝙蝠和二小姐走同一条边付出的代价可能不同。但是如果某一只蝙蝠与二小姐碰面,那么二小姐由于蝙蝠的引导,以后的所有路程可以不支付代价。(也就是相当于二小姐和某只蝙蝠都走到某点,之后无视二小姐的存在。)现在已知所有蝙蝠,二小姐和目标集合点的位置,请你求出所有蝙蝠和二小姐行走代价的和的最小值。
输入文件
第一行是55个正整数,n,m,k,S,Tn,m,k,S,T,分别代表无向图点数,边数,蝙蝠的数量,二小姐所在起点的编号,目标点的编号。
第二行是kk个正整数,分别代表大小姐每个蝙蝠所在的起点的编号。
接下来有mm行,每行有44个正整数,u,v,q,pu,v,q,p,分别是该边的起点、终点,蝙蝠通过该路花费的代价,二小姐通过该路花费的代价。
输出文件
一行,一个整数,所有人物达到终点所需要的代价的和的最小值。
样例
[input]
5 5 2 3 4
1 5
1 2 3 5
3 2 3 5
2 4 4 9
3 4 9 6
5 4 1 1
[output]
13
Extra Input Sample
Extra Output Sample
样例解释
11号蝙蝠从 11 到 22,花费 33
二小姐从 33 到 22,花费 55,遇见蝙蝠,之后不计算费用
11 号蝙蝠从 22 到 44,花费 44
22 号蝙蝠从 55 到 44,花费 11
总计 1313
数据约定
对于 30% 的数据,1≤n≤2001≤n≤200
对于 另外20% 的数据, S=TS=T。
对于 另外20% 的数据, 1≤k≤5,1≤n≤1000,1≤m≤100001≤k≤5,1≤n≤1000,1≤m≤10000。
对于 100% 的数据, 1≤n≤10000,1≤m≤100000,1≤k≤10000,1≤S,T,u,v≤n,1≤p,q≤10001≤n≤10000,1≤m≤100000,1≤k≤10000,1≤S,T,u,v≤n,1≤p,q≤1000不保证蝙蝠起点互不相等,数据中可能有重边和自环,保证所有点均能走到 T 点(即不存在无解情况)。
【思路】推出一个式子,求三次最短路,以T为起点的,以S为起点的,以n+1为起点的
【注意】数组大小
【代码】
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#define ll long long
#define maxn 10004
#define maxm 1000006
#define inf 1000000009
using namespace std;
typedef pair<ll,int>pa;
int n,m,k,s,t,bat[maxn],to[maxm],nxt[maxm],fst[maxn],w1[maxm],w2[maxm],cnt=0;
ll d1[maxn],d2[maxn],d3[maxn],mn;
priority_queue<pa,vector<pa>,greater<pa> >q;
int get(){
char c;while(!isdigit(c=getchar()));
int v=c-48;while(isdigit(c=getchar()))v=v*10+c-48;
return v;
}
void add(int x,int y,int z1,int z2){to[++cnt]=y;nxt[cnt]=fst[x],fst[x]=cnt,w1[cnt]=z1,w2[cnt]=z2;}
bool vst[maxn];
void dij(int x,ll *d,bool flag){
ll dis;while(!q.empty())q.pop();
for(int i=1;i<=n;++i)d[i]=inf;
memset(vst,0,sizeof(vst));
d[x]=0;q.push(make_pair(d[x],x));
while(!q.empty()){
int now=q.top().second;q.pop();
if(vst[now])continue;
vst[now]=1;
for(int i=fst[now];i;i=nxt[i]){
if(!flag)dis=w2[i];
else dis=w1[i];
if(d[to[i]]>dis+d[now]){
d[to[i]]=dis+d[now];
q.push(make_pair(d[to[i]],to[i]));
}
}
}
}
void init(){
int u,v,z1,z2;
n=get(),m=get(),k=get(),s=get(),t=get();
for(int i=1;i<=k;++i)bat[i]=get();
for(int i=1;i<=m;++i){
u=get(),v=get(),z1=get(),z2=get();
add(u,v,z1,z2);
add(v,u,z1,z2);
}
}
void solveit(){
dij(t,d1,1);dij(s,d2,0);mn=inf;
for(int i=1;i<=k;++i)add(n+1,bat[i],-d1[bat[i]],0);
dij(n+1,d3,1);
for(int i=1;i<=n;++i){
mn=min(mn,d1[i]+d2[i]+d3[i]);
}
for(int i=1;i<=k;++i)mn+=d1[bat[i]];
printf("%lld\n",mn);
}
int main(){
init();
solveit();
return 0;
}