题意:
给一个图和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; }
poj 4046 Sightseeing 枚举思想在spfa中的应用
原文地址:http://blog.csdn.net/sepnine/article/details/44733203