最短路和次短路条数
来源:互联网 发布:HTML如何删除某个js 编辑:程序博客网 时间:2024/06/10 05:34
问题描述:
给你一张无向图或有向图,要你求任意两点的最短路条数或次短路条数
算法描述:
1,最短路:
对于最短路条数,我们很容易想到的是加法原则,我们可以在用dij求最短路的时候,
当dis[j]=dis[to]+mp[to][j]时我们知道j点此时有两条不同的路径相同的路径经过,所以
我们可以用个数组cnt[j]表示经过j点的最短路条数,所以我们可以得到此时cnt[j]+=cnt[to]
而当大于时cnt[j]=cnt[to]
2,次短路:
对于次短路,我们可以采取和最短路一样的策略,也是加法原则,我们可以用个二维的
数组来分别记录最短路和次短路,即dis[][2],cnt[][2],而我们知道次短路是要比最短路长的,所以
当更新最短路时我们知道更新前的最短路要比更新后的最短路要长,所以我们不妨让此时的
次短路等于更新前的最短路,而当最短路不能更新即,dis[j]<dis[to]+mp[to][j]时,我们可以让
此时的次短路来和后面的比较,如果比后面的大,说明此时次短路应该更新,如果等于说明该
点次短路条数增加!
算法例子:
1,HDU-3191 :求次短路长度和条数,但这题有个坑就是边权值可以为0,所以如果用优先队列的话会出错,普通的就行。
AC代码:
#include<algorithm>#include<cstdio>#include<queue>using namespace std;const int maxn = 1e3+10;const int inf = 1e9;class Edge{public: int v,w,nex;};class num_Shortpath{public: int n,m,e; int dis[maxn][2], cnt[maxn][2],vis[maxn][2],hed[maxn]; Edge edge[maxn*maxn]; queue<pair<int,int> >q; void add(int u,int v,int w){ edge[e].v=v,edge[e].w=w,edge[e].nex=hed[u],hed[u]=e++; } void init(){ int s0,e0; while( ~scanf("%d%d%d%d",&n,&m,&s0,&e0)){ s0++,e0++; for(int i=1;i<=n;i++)hed[i]=-1,vis[i][0]=vis[i][1]=0;e=1; for(int i=0;i<m;i++){ int u,v,w;scanf("%d%d%d",&u,&v,&w); u++,v++; add(u,v,w); } spfa(s0); printf("%d %d\n",dis[e0][1],cnt[e0][1]); } } void spfa(int u){ for(int i=1;i<=n;i++){ dis[i][0]=inf,cnt[i][1]=0; dis[i][1]=inf,cnt[i][1]=0; vis[i][0]=vis[i][1]=0; } dis[u][0]=0,cnt[u][0]=1; q.push(make_pair(u,0)); while(!q.empty()){ int to = q.front().first,flag = q.front().second;q.pop(); if(vis[to][flag])continue; vis[to][flag]=1; for(int i=hed[to];~i;i=edge[i].nex){ int j = edge[i].v; int tmp = dis[to][flag]+edge[i].w; if(dis[j][0]>tmp){ if(dis[j][0]!=inf){ dis[j][1]=dis[j][0]; cnt[j][1]=cnt[j][0]; q.push(make_pair(j,1)); } dis[j][0]=tmp; cnt[j][0]=cnt[to][flag]; q.push(make_pair(j,0)); } else if(dis[j][0]==tmp){ cnt[j][0]+=cnt[to][flag]; } else if(dis[j][1]>tmp){ dis[j][1]=tmp; cnt[j][1]=cnt[to][flag]; q.push(make_pair(j,1)); } else if(dis[j][1]==tmp){ cnt[j][1]+=cnt[to][flag]; } } } }}ns;int main(){ ns.init(); return 0;}
2,HDU1688-分别求最短路条数和次短路条数,要求差值为1,这个就要用优先队列才可以过
AC代码:
#include<algorithm>#include<cstdio>#include<queue>using namespace std;const int maxn = 1e3+10;const int inf = 1e9;int dis[maxn][2];class Edge{public: int v,w,nex;};class Nod{public: int first,second; Nod(int a,int b){ first = a,second=b; } bool operator <(const Nod &t)const{ return dis[first][second]>dis[t.first][t.second]; }};class num_Shortpath{public: int n,m,e; int cnt[maxn][2],vis[maxn][2],hed[maxn]; Edge edge[maxn*maxn]; priority_queue<Nod>q; void add(int u,int v,int w){ edge[e].v=v,edge[e].w=w,edge[e].nex=hed[u],hed[u]=e++; } void init(){ int t;scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)hed[i]=-1,vis[i][0]=vis[i][1]=0;e=1; for(int i=0;i<m;i++){ int u,v,w;scanf("%d%d%d",&u,&v,&w); add(u,v,w); } int u,v;scanf("%d%d",&u,&v); spfa(u); if(dis[v][0]==dis[v][1]-1) printf("%d\n",cnt[v][0]+cnt[v][1]); else printf("%d\n",cnt[v][0]); } } void spfa(int u){ for(int i=1;i<=n;i++){ dis[i][0]=inf,cnt[i][1]=0; dis[i][1]=inf,cnt[i][1]=0; vis[i][0]=vis[i][1]=0; } dis[u][0]=0,cnt[u][0]=1; q.push(Nod(u,0)); while(!q.empty()){ int to = q.top().first,flag = q.top().second;q.pop(); if(vis[to][flag])continue; vis[to][flag]=1; for(int i=hed[to];~i;i=edge[i].nex){ int j = edge[i].v; int tmp = dis[to][flag]+edge[i].w; if(dis[j][0]>tmp){ if(dis[j][0]!=inf){ dis[j][1]=dis[j][0]; cnt[j][1]=cnt[j][0]; q.push(Nod(j,1)); } dis[j][0]=tmp; cnt[j][0]=cnt[to][flag]; q.push(Nod(j,0)); } else if(dis[j][0]==tmp){ cnt[j][0]+=cnt[to][flag]; } else if(dis[j][1]>tmp){ dis[j][1]=tmp; cnt[j][1]=cnt[to][flag]; q.push(Nod(j,1)); } else if(dis[j][1]==tmp){ cnt[j][1]+=cnt[to][flag]; } } } }}ns;int main(){ ns.init(); return 0;}
- 最短路和次短路条数
- POJ_3463_Sightseeing(最短路/次短路条数)
- poj3463Sightseeing(最短路条数+次短路条数)
- HDU-1688 Sightseeing 最短路与“次短路”条数
- hdu 1688 Sightseeing【最短路,次短路条数】
- hdu 1688 Sightseeing(最短路+次短路条数)
- POJ-3463: Sightseeing 【最短路次短路及条数】
- hdu 6181 Two Paths -最短路条数+次短路
- HDU 1688 Sightseeing 求最短路和次短路条数之和
- 最短路和次短路的条数(dijstra算法或spfa算法)POJ3463
- 优先队列优化的求最短路和次短路条数以及长度的模板
- 最短路条数
- poj 3463 统计次短路条数+最短路条数
- HDU3191 次短路条数
- 最短路 & 次短路
- poj 3255 最短路和次短路
- poj 3463 最短路和次短路
- POJ 3463 Sightseeing (最短路&次短路条数问题)
- 对于特殊的边界值特殊考虑的问题
- java 多线程总结
- VIM的使用
- Android学习笔记--多渠道打包
- 将有序数组转变成平衡二叉查找树
- 最短路和次短路条数
- 一名信竞选手的第二个家
- 20行代码实现微信拜年消息智能自动回复
- mvn 阶段被执行几次
- vue学习第三节
- 笔记之android 动画1—插值器
- php学习笔记 -- 关于连接符与单双引号
- 实验吧 迷宫大逃亡 By Assassin
- [学习笔记]设计模式[3]-{工厂模式}