首页 > 代码库 > 最短路和次短路问题,dijkstra算法

最短路和次短路问题,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=0118         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 0130

 

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