当前位置: 代码迷 >> 综合 >> poj 4046 Sightseeing 枚举思想在spfa中的应用
  详细解决方案

poj 4046 Sightseeing 枚举思想在spfa中的应用

热度:70   发布时间:2024-01-19 05:50:39.0

题意:

给一个图和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");elseprintf("%I64d\n",ans[i]);printf("\n");} return 0; 	
}