题意:
给一个图和q个询问,每个询问查询图中两点的(距离+路径上最大值)的最小值。
分析:
枚举路径上的最大值做spfa,这题丫的卡常数。。。队列用stl的就等着tle吧。
代码:
//poj 4046
//sep9
#include <iostream>
#define inf ((~(0ULL))>>1)
using namespace std;
const int maxN=1024;
const int maxM=20012;
typedef long long ll;
struct Edge
{
int v,next;
ll w;
}e[maxM*2];
int n,m,ecnt,q;
int head[maxN],a[maxM],b[maxM];
ll d[maxN],ans[maxM],price[maxN];
bool inq[maxN];
int myque[maxM*4];
void addedge(int a,int b,ll c)
{
e[ecnt].v=b;e[ecnt].w=c;e[ecnt].next=head[a];head[a]=ecnt++;
e[ecnt].v=a;e[ecnt].w=c;e[ecnt].next=head[b];head[b]=ecnt++;
}
void query(int s)
{
int i;
for(i=1;i<=n;++i){
d[i]=inf;
inq[i]=0;
}
d[s]=0,inq[s]=1;
int h=0,r=0;
myque[r++]=s;
while(h<r){
int u=myque[h++];
inq[u]=0;
for(i=head[u];i!=-1;i=e[i].next){
if(price[e[i].v]>price[s]) continue;
if(d[u]+e[i].w<d[e[i].v]){
d[e[i].v]=d[u]+e[i].w;
if(inq[e[i].v]==0){
inq[e[i].v]=1;
myque[r++]=e[i].v;
}
}
}
}
for(i=1;i<=q;++i)
if(d[a[i]]!=inf&&d[b[i]]!=inf&&ans[i]>d[a[i]]+d[b[i]]+price[s])
ans[i]=d[a[i]]+d[b[i]]+price[s];
}
int main()
{
while(scanf("%d%d",&n,&m)){
if(m==0&&n==0) break;
int i;
for(i=1;i<=n;++i)
scanf("%lld",&price[i]);
ecnt=0;
memset(head,-1,sizeof(head));
while(m--){
int a,b;
ll c;
scanf("%d%d%lld",&a,&b,&c);
addedge(a,b,c);
}
scanf("%d",&q);
for(i=1;i<=q;++i){
scanf("%d%d",&a[i],&b[i]);
ans[i]=inf;
}
for(i=1;i<=n;++i)
query(i);
for(i=1;i<=q;++i)
if(ans[i]==inf)
printf("-1\n");
else
printf("%I64d\n",ans[i]);
printf("\n");
}
return 0;
}