最短路和次短路问题,dijkstra算法

  1 /*
  2  *题目大意:
  3  *在一个有向图中,求从s到t两个点之间的最短路和比最短路长1的次短路的条数之和;
  4  *
  5  *算法思想:
  6  *用A*求第K短路,目测会超时,直接在dijkstra算法上求次短路;
  7  *将dist数组开成二维的,即dist[v][2],第二维分别用于记录最短路和次短路;
  8  *再用一个cnt二维数组分别记录最短路和次短路的条数;
  9  *每次更新路径的条数时,不能直接加1,,应该加上cnt[u][k],k为次短路径或者最短路径的标记;
 10  *图有重边,不能用邻接矩阵存储;
 11  *不知道为什么,题目上说的是N and M, separated by a single space, with 2≤N≤1000 and 1 ≤ M ≤ 10000;
 12  *而我的代码硬是把N开成1W了才过,求解释,RE了无数次,擦;
 13 **/ 
 14 #include<iostream> 
 15 #include<cstdio> 
 16 #include<cstring> 
 17 #include<string> 
 18 #include<algorithm> 
 19 using namespace std; 
 20    
 21 const int N=11111; 
 22 const int M=111111; 
 23 const int INF=0xffffff; 
 24    
 25 struct node 
 26 { 
 27     int to; 
 28     int w; 
 29     int next; 
 30 }; 
 31    
 32 node edge[N]; 
 33 int head[N]; 
 34    
 35 int dist[N][2],cnt[N][2]; 
 36 bool vis[N][2]; 
 37 int n,m,s,t,edges; 
 38    
 39 void addedge(int u,int v,int w) 
 40 { 
 41     edge[edges].w=w; 
 42     edge[edges].to=v; 
 43     edge[edges].next=head[u]; 
 44     head[u]=edges++; 
 45 } 
 46    
 47 int dijkstra() 
 48 { 
 49     int k; 
 50     for(int i=0; i<=n; i++) 
 51     { 
 52         dist[i][0]=dist[i][1]=INF; 
 53         vis[i][0]=vis[i][1]=0; 
 54         cnt[i][0]=cnt[i][1]=0; 
 55     } 
 56     cnt[s][0]=1,dist[s][0]=0; 
 57    
 58     for(int i=1; i<=n*2; i++) 
 59     { 
 60         int u=-1; 
 61         int min_dist=INF; 
 62         for(int j=1; j<=n; j++) 
 63             for(int flag=0; flag<2; flag++) 
 64                 if(!vis[j][flag]&&dist[j][flag]<min_dist) 
 65                 { 
 66                     min_dist=dist[j][flag]; 
 67                     u=j; 
 68                     k=flag; 
 69                 } 
 70         if(u==-1) 
 71             break; 
 72         vis[u][k]=true; 
 73         for(int e=head[u]; e!=-1; e=edge[e].next) 
 74         { 
 75             int j=edge[e].to; 
 76             int tmp=dist[u][k]+edge[e].w; 
 77    
 78             if(tmp<dist[j][0])//tmp小于最短路径长: 
 79             { 
 80                 dist[j][1]=dist[j][0];//次短路径长 
 81                 cnt[j][1]=cnt[j][0];//次短路径计数 
 82                 dist[j][0]=tmp;//最短路径长 
 83                 cnt[j][0]=cnt[u][k];//最短路径计数 
 84             } 
 85    
 86             else if(tmp==dist[j][0])//tmp等于最短路径长: 
 87             { 
 88                 cnt[j][0]+=cnt[u][k];//最短路径计数 
 89             } 
 90    
 91             else if(tmp<dist[j][1])//tmp大于最短路径长且小于次短路径长: 
 92             { 
 93                 dist[j][1]=tmp;//次短路径长 
 94                 cnt[j][1]=cnt[u][k];//次短路径计数 
 95             } 
 96    
 97             else if(tmp==dist[j][1])//tmp等于次短路径长: 
 98             { 
 99                 cnt[j][1]+=cnt[u][k];//次短路径计数 
100             } 
101         } 
102     } 
103    
104     int res=cnt[t][0]; 
105     if(dist[t][0]+1==dist[t][1])//判断最短路和次短路是否相差1 
106         res+=cnt[t][1]; 
107     return res; 
108 } 
109    
110 int main() 
111 { 
112     //freopen("C:\\Users\\Administrator\\Desktop\\kd.txt","r",stdin); 
113     int tcase; 
114     scanf("%d",&tcase); 
115     while(tcase--) 
116     { 
117         edges=0; 
118         scanf("%d%d",&n,&m); 
119         memset(head,-1,sizeof(head)); 
120         int u,v,w; 
121         for(int i=0; i<m; i++) 
122         { 
123             scanf("%d%d%d",&u,&v,&w); 
124             addedge(u,v,w); 
125         } 
126         scanf("%d%d",&s,&t); 
127         printf("%d\n",dijkstra()); 
128     } 
129     return 0; 
130 }  
时间: 2024-12-11 03:42:41

最短路和次短路问题,dijkstra算法的相关文章

最短路:我的理解--Dijkstra算法

最短路径:Dijkstra算法 用来计算从一个点到其他所有点的最短路径的算法,是一种单源最短路径算法.也就是说,只能计算起点只有一个的情况. Dijkstra的时间复杂度是O (N2),它不能处理存在负边权的情况. 算法描述:        设起点为s,dis[v]表示从s到v的最短路径,pre[v]为v的前驱节点,用来输出路径.        a)初始化:dis[v]=∞(v≠s); dis[s]=0; pre[s]=0;        b)For (i = 1; i <= n-1 ; i++

最短路 Dijkstra算法

Dijksitra算法求最短路仅仅适用于不存在右边是负权的情况(Bellman-Ford算法没有这一个限制).主要特点是从起点为中心向外层层扩展,直到扩展到终点为止. 最短路的最优子结构性质 即一个最短路路径中经过的所有点这条路均是其最短路.(反证法易证) Dijkstra基本思路: ①找到最短距离已经确定的顶点,从它出发更新相邻顶点的最短距离 ②此后不需要再关心1中的"最短距离已经确定的顶点" 在最开始的时候,只有起点的最短距离是确定的.而在尚未使用过的顶点中,距离d[i]最小的顶点

ACM: HDU 2544 最短路-Dijkstra算法

HDU 2544最短路 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据.每组数据第一行是两个整数N.M(N<=100,M<

Dijkstra算法 --- 单源最短路

Dijkstra算法适用于边权值为正的情况,可用于计算正权图上的单元最短路. 其伪代码如下: 设d[v0] = 0, 其他d[i] = INF 循环n次{ 在所有未标号的结点中,选取d值最小的结点x 给结点x加上永久标号 对于从x出发的所有边,执行松弛操作. } //松弛操作的伪代码如下: RELAX(u,v,w) if(u.d + w(u,v) < v.d){ v.d = w.d + w(u,v); pre[v] = u; } Dijkstra算法代码: /* Dijkstra 单源最短路算法

HDU2544 最短路【Dijkstra算法】

最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 34628    Accepted Submission(s): 15003 Problem Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找

POJ-3268-最短路(dijkstra算法)

Silver Cow Party Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 12494   Accepted: 5568 Description One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the big cow party to be held at farm #X (1 ≤ X

HDU 2544 最短路(我的dijkstra算法模板、SPAFA算法模板)

思路:这道题是基础的最短路径算法,可以拿来试一下自己对3种方法的理解 dijkstra主要是从第一个点开始枚举,每次枚举出当当前最小的路径,然后再以那最小的路径点为起点,求出它到其它未标记点的最短距离 bellman-ford 算法则是假设有向网中有n 个顶点.且不存在负权值回路,从顶点v1 和到顶点v2 如果存在最短路径,则此路径最多有n-1 条边.这是因为如果路径上的边数超过了n-1 条时,必然会重复经过一个顶点,形成回路:而如果这个回路的权值总和为非负时,完全可以去掉这个回路,使得v1到v

单源最短路Dijkstra算法——matlab实现

迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本思想 通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算). 此外,引进两个集合S和U.S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求出最短路径的顶点(以及该顶点到起点s的距离). 初始时,S中只有起点s:U中是除s之外的顶点,并且U中顶点的路径是"起点s

【裸单源最短路:Dijkstra算法两种版本】hdu 1874 畅通工程续

Source : hdu 1874 畅通工程续 http://acm.hdu.edu.cn/showproblem.php?pid=1874 Problem Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多.这让行人很困扰. 现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离. Input 本题目包含多组数据,请处理到文件结束.