HDU 1688 Sightseeing

#include <stdio.h>
#define MAX_CITIES 1000
#define MAX_ROADS 10000
#define INF 1000000


int numOfCities, numOfRoads;
typedef struct Road{
	int to;
	int len;
	int next;
}Road;
Road RoadArray[MAX_ROADS + 1];
int RoadNum;
int head[MAX_CITIES + 1];
int start, final;
int dist[MAX_CITIES + 1][2];
int count[MAX_CITIES + 1][2];
int visited[MAX_CITIES + 1][2];

int main(){

	int testCases;
	scanf("%d", &testCases);
	while (testCases--){
		scanf("%d%d", &numOfCities, &numOfRoads);

		int i;
		for (i = 1; i <= numOfCities; i++){
			visited[i][0] = visited[i][1] = 0;
			dist[i][0] = dist[i][1] = INF;
			head[i] = 0;
		}

		RoadNum = 0;
		int from, to, len;
		for (i = 1; i <= numOfRoads; i++){
			scanf("%d%d%d", &from, &to, &len);
			RoadNum++;
			RoadArray[RoadNum].to = to;
			RoadArray[RoadNum].len = len;
			RoadArray[RoadNum].next = head[from];
			head[from] = RoadNum;
		}

		scanf("%d%d", &start, &final);

		dist[start][0] = 0;
		count[start][0] = 1;

		int doubleCities = numOfCities << 1;
		
		for (i = 1; i <= doubleCities; i++){
			int distance = INF;
			int city = 0;
			int zeroOrOne;
			int j;
			for (j = 1; j <= numOfCities; j++){
				if (visited[j][0] == 0 && dist[j][0] < distance){
					distance = dist[j][0];
					city = j;
					zeroOrOne = 0;
				} else if (visited[j][1] == 0 && dist[j][1] < distance){
					distance = dist[j][1];
					city = j;
					zeroOrOne = 1;
				}
			}

			if (city == 0){
				break;
			}

			visited[city][zeroOrOne] = 1;

 			for (j = head[city]; j != 0; j = RoadArray[j].next){
				to = RoadArray[j].to;
				int newDist = distance + RoadArray[j].len;

				if (newDist < dist[to][0]){
					dist[to][1] = dist[to][0];
					count[to][1] = count[to][0];

					dist[to][0] = newDist;
					count[to][0] = count[city][zeroOrOne];
				} else if (newDist == dist[to][0]){
					count[to][0] += count[city][zeroOrOne];
				} else if (newDist < dist[to][1]){
					dist[to][1] = newDist;
					count[to][1] = count[city][zeroOrOne];
				} else if (newDist == dist[to][1]){
					count[to][1] += count[city][zeroOrOne];
				}
			}
		}

		int num = count[final][0];
		if (dist[final][1] - 1 == dist[final][0]){
			num += count[final][1];
		}
		printf("%d\n", num);	
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值