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

poj 3463 Sightseeing(最短路+次短路)

时间:2014-05-24 21:50:31      阅读:287      评论:0      收藏:0      [点我收藏+]

标签:最短路

http://poj.org/problem?id=3463


大致题意:给出一个有向图,从起点到终点求出最短路和次短路的条数之和。


解法:

用到的数组:dis[i][0]:i到起点的最短路,dis[i][1]:i到起点的严格次短路

vis[i][0],vis[i][1]:同一维的vis数组,标记距离是否已确定

sum[i][0]:i到起点的最短路条数,sum[i][1]:i到起点的次短路条数


同一维dijkstra,内循环先找出最短的距离(次短路或最短路)d,然后枚举与该点相连的点:

if(d < 最小)  更新最小和次小,包括距离以及路径条数

else if(d == 最小) 更新最短路径条数

else if(d < 次小) 更新次小,包括次小距离路径条数

else if(d == 次小) 更新次小路径条数


同一维不同的是外层循环次数为2*n-1次,因为更新最小n-1次,更新次小n次。

邻接表建图


#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#define LL long long
#define _LL __int64
using namespace std;
const int INF = 1<<28;
const int maxn = 1010;
const int maxm = 10010;

int cnt,head[maxn];
struct node
{
	int v,w,next;
}edge[maxm];
int n,m;
int s,t;
int dis[maxn][2];
int vis[maxn][2];
int sum[maxn][2];

void init()
{
	memset(head,-1,sizeof(head));
	cnt = 0;
}

void add(int u, int v, int w)
{
	edge[cnt] = (struct node){v,w,head[u]};
	head[u] = cnt++;
}

void dijkstra()
{
	for(int i = 1; i <= n; i++)
	{
		dis[i][0] = INF;
		dis[i][1] = INF;
	}
	memset(vis,0,sizeof(vis));
	memset(sum,0,sizeof(sum));

	dis[s][0] = 0;
	sum[s][0] = 1;

	for(int i = 1; i <= 2*n-1; i++)
	{
		int Min = INF,pos = -1,flag;
		for(int j = 1; j <= n; j++)
		{
			if(!vis[j][0] && Min > dis[j][0])
			{
				Min = dis[j][0];
				pos = j;
				flag = 0;
			}
			else if(!vis[j][1] && Min > dis[j][1])
			{
				Min = dis[j][1];
				pos = j;
				flag = 1;
			}
		}
		if(pos == -1)
			break;

		vis[pos][flag] = 1;

		for(int j = head[pos]; j != -1; j = edge[j].next)
		{
			int v = edge[j].v;
			int w = edge[j].w;

			if(dis[v][0] > dis[pos][flag] + w) //比最小要小
			{
				dis[v][1] = dis[v][0];
				sum[v][1] = sum[v][0];
				dis[v][0] = dis[pos][flag] + w;
				sum[v][0] = sum[pos][flag];
			}
			else if(dis[v][0] == dis[pos][flag] + w) //等于最小
			{
				sum[v][0] += sum[pos][flag];
			}
			else if(dis[v][1] > dis[pos][flag] + w) //比次小要小
			{
				dis[v][1] = dis[pos][flag] + w;
				sum[v][1] = sum[pos][flag];
			}
			else if(dis[v][1] == dis[pos][flag] + w) //等于次小
			{
				sum[v][1] += sum[pos][flag];
			}
		}
	}

	if(dis[t][1] == dis[t][0] + 1)
		sum[t][0] += sum[t][1];
	printf("%d\n",sum[t][0]);
}

int main()
{
	int test;
	int u,v,w;
	scanf("%d",&test);
	while(test--)
	{
		init();
		scanf("%d %d",&n,&m);
		for(int i = 0; i < m; i++)
		{
			scanf("%d %d %d",&u,&v,&w);
			add(u,v,w);
		}
		scanf("%d %d",&s,&t);
		dijkstra();
	}
	return 0;
}




poj 3463 Sightseeing(最短路+次短路),布布扣,bubuko.com

poj 3463 Sightseeing(最短路+次短路)

标签:最短路

原文地址:http://blog.csdn.net/u013081425/article/details/26607053

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