码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-03-30 09:26:43      阅读:166      评论:0      收藏:0      [点我收藏+]

标签:poj   算法   

题意:

给一个图和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中的应用

标签:poj   算法   

原文地址:http://blog.csdn.net/sepnine/article/details/44733203

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!