uva 11374 Airport Express

题目:Airport Express


题意:有一张n个点的带权无向图,其中有m条经济线,k条商务线。规定经济线可以走任意次,但只能走一或零条商务线。问从s走到e的最短路。


思路:

先用dijkstra求出任意一点到起点和终点的最短路,记作dists[],diste[]。

再枚举乘坐的是那一条商务线,记作X->Y。

最后的结果就是min{dists[X]+v[x][y]+diste[y]}。


注意:

1、priority_queue是大根堆,小于运算符不能定反了。

2、商务线也是无向的,X->Y和Y->X要算两遍。

3、输出格式。


代码:

#include
using namespace std;

#define maxn 500
#define maxm 1000

struct Pair {
	int x,y;
	Pair(int xx=0,int yy=0) {
		x=xx,y=yy;
	}
	bool operator < (const Pair& oth) const {
		return x>oth.x;
	}
};

int n;	//n个点
int s,e;	//起点
int m,k;	//边

vector a[maxn+5];	//经济线

Pair b[maxm*2+5];	//商业线
int v[maxm*2+5];

int dists[maxn+5];	//起点到每个点的最短路
int diste[maxn+5];	//终点到每个点的最短路

vector ans1,ans2;

void init() {	//初始化
	for(int i=1; i<=maxn; i++) a[i].clear();
	ans1.clear(),ans2.clear();
}

void readin() {	//读入
	scanf("%d",&m);
	for(int i=1; i<=m; i++) {
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		a[x].push_back(Pair(y,z));
		a[y].push_back(Pair(x,z));
	}
	scanf("%d",&k);
	for(int i=1; i<=k; i++) {
		scanf("%d%d%d",&b[i].x,&b[i].y,&v[i]);
		b[i+k].x=b[i].y,b[i+k].y=b[i].x,v[i+k]=v[i];
	}
	k*=2;
}

void dijkstra(int* dist,int bg) {	//dijkstra
	priority_queue p;
	bool c[maxn+5]= {0};

	for(int i=1; i<=n; i++) dist[i]=(1<<29);
	dist[bg]=0;
	p.push(Pair(0,bg));

	while(!p.empty()) {
		Pair x=p.top();
		p.pop();
		if(c[x.y]) continue;
		c[x.y]=true;

		for(int i=0; ix.x+a[x.y][i].y) {
				dist[a[x.y][i].x]=x.x+a[x.y][i].y;
				p.push(Pair(dist[a[x.y][i].x],a[x.y][i].x));
			}
		}
	}
}

void find(int* dist,int x,vector& ans) {	//寻找路径
	while(dist[x]) {
		ans.push_back(x);
		for(int i=0; i=0; i--) {
			printf("%d ",ans1[i]);
		}
		printf("%d",ans2[0]);
		for(int i=1; i=0; i--) {
			printf(" %d",ans1[i]);
		}
		printf("\nTicket Not Used\n%d\n",ans);
	}
}

int main() {
	int t=0;
	while(~scanf("%d%d%d",&n,&s,&e)) {
		if(t) printf("\n");
		t++;
		init();
		readin();
		dijkstra(dists,s);
		dijkstra(diste,e);
		print();
	}
	return 0;
}

你可能感兴趣的:(uva,蓝书,图论,最短路,枚举)