poj 3463 统计次短路条数+最短路条数

来源:互联网 发布:股票交易系统测试软件 编辑:程序博客网 时间:2024/05/22 00:35

题意:给一个有向图,问从s到t的     最短路  和    比最短路距离长1的次短路 
思路:Dijkstra(不使用heap)
1.每次维护次短路和最短路的长度,与最短路和次短路的条数
最后输出结果的时候判断当前最短路和次短路的长度差是否为1
2.维护方法:
dis[i][0]:到点i的最短路长度  dis[i][1]:到i点的次短路长度
cnt[i][0]:到点i的最短路的路数   cnt[i][1]:到i点的最短路条数
vis表示最短路或次短路是否已经算出 
每次找到和当前集合中距离最近的点加入集合
先更新最短路,如果小于原来的路径,将原来的最短路设为次短路,将新加入的点设为最短路
如果和最短路相等,直接将新加入点的方案数累加到原来的方案数中;
如果不能更新最短路,再更新次短路,更新步骤同上
总之 if balala else blala if blala else blala.......


代码如下:

#include <cstdio>#include <algorithm>#include <cstring>#include <cstdlib>#include <iostream>#include <cassert>#include <sstream>#include <numeric>#include <climits>#include <string>#include <cctype>#include <ctime>#include <iomanip>#include <cmath>#include <vector>#include <queue>#include <list>#include <map>#include <set>#define INF 29000#define MAX 1000000000using namespace std;struct data{int to,len,next;}bian[2*INF];int t,size,first[INF],casee;int vis[INF][2],cnt[INF][2],dis[INF][2];int n,m,x,y,z,s;//dis[i][0]:到点i的最短路  dis[i][1]次短路 //cnt[i][0]:到点i的最短路的路数 //vis表示最短路或次短路是否已经算出 void add(int x,int y,int z){size++;bian[size].next=first[x];first[x]=size;bian[size].to=y;bian[size].len=z;}void Dijkstra(int s,int t){dis[s][0]=0;cnt[s][0]=1;int maxx,pos,flag;for(int i=1;i<=2*n-1;i++){int minn=MAX;for(int j=1;j<=n;j++){if(!vis[j][0]&&minn>dis[j][0]){minn=dis[j][0];pos=j;flag=0;} elseif(!vis[j][1]&&minn>dis[j][1]){minn=dis[j][1];pos=j;flag=1;}}if(minn==MAX)break;vis[pos][flag]=1;for(int u=first[pos];u;u=bian[u].next){int to=bian[u].to,len=bian[u].len;if(dis[to][0]>minn+len){dis[to][1]=dis[to][0];dis[to][0]=minn+len;cnt[to][1]=cnt[to][0];cnt[to][0]=cnt[pos][flag];}else if(dis[to][0]==minn+len)cnt[to][0]+=cnt[pos][flag];else{if(dis[to][1]>minn+len){dis[to][1]=minn+len;cnt[to][1]=cnt[pos][flag];}else if(dis[to][1]==minn+len)cnt[to][1]+=cnt[pos][flag];}}}int ans;if(dis[t][0]+1==dis[t][1])ans=cnt[t][0]+cnt[t][1];else ans=cnt[t][0];cout<<ans<<endl;}void init(){memset(vis,0,sizeof(vis));memset(first,0,sizeof(first));size=0;for(int i=1;i<=n;i++)dis[i][0]=dis[i][1]=INF;memset(cnt,0,sizeof(cnt));}int main(){//freopen("in.in","r",stdin);ios::sync_with_stdio(false);cin.tie(NULL);cin>>casee;while(casee--){cin>>n>>m;init();for(int i=1;i<=m;i++){cin>>x>>y>>z;add(x,y,z);}cin>>s>>t;Dijkstra(s,t);}}



0 0
原创粉丝点击