标签:最短路
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
标签:最短路
原文地址:http://blog.csdn.net/u013081425/article/details/26607053