zoukankan      html  css  js  c++  java
  • HDU3191 How Many Paths Are There

    ~~~~~~HDU3191 How Many Paths Are There ~~~~~~

    大致题意:

    给出一个有向图,求其次短路径数。

    思路:

    1. 首先,用一个邻接矩阵储存图,

      再用几个数组记录标程
    2. [0]表示最短路,[1]表示次短路。初始化图为-1,输入图,完成图的构建

    在进行 dijkstra 的过程中记录两个数组:dist0 和 dist1,分别表示最短路和次短路的答案。每次更新时需要依次判断是否可以更新次短路和最短路的值。由于需要计算次短路,所以调整后的 dijkstra 算法需要至少循环 2n 次才可以获得最终答案。

    4.if (min + map[k][j] < dis[j][0]) 表示可以更新最短,那么同时次短也会被原来的最短所更新掉,产生了两个新状态,都要添加到队列中。

    else if (min + map[k][j] == dis[j][0]) 表示最短路径增多了。

    else if (min + map[k][j] > dis[j][0] && min + map[k][j] < dis[j][1])表示可以更新次短路,状态有改变,需要将新状态添加到队列中。

    else if (min + map[k][j] == dis[j][1])表示次短路径增多了。

    #include<iostream>
    #include<string.h>
    using namespace std;
    #define M 51
    #define inf 0x3f3f3f3f
    int map[M][M];
    int dis[M][2];
    int vis[M][2];
    int cnt[M][2];
    int n, m, s, e;
    void dij() {
        for(int i=0;i<n;i++){
            cnt[i][0]=0;
            cnt[i][1]=0;
            vis[i][0]=0;
            vis[i][1]=0;
        }
        //cout<<cnt[2][0]<<cnt[2][1];
    //    vis[s][0]= 1;
    //    
        for (int i = 0; i < n; i++) {
            //dis[i][0] = map[s][i];
            dis[i][0]=inf;
            dis[i][1] = inf;
        }
        dis[s][0]=0;
        cnt[s][0]=1;
        int min = inf;
        int k;
        int flog;
        for (int i = 0; i < n*2; i++) {
            min = inf;
            for (int j = 0; j < n; j++) {
                if (dis[j][0] < min && !vis[j][0]) {
                    k = j;
                    flog=0;
                    min = dis[j][0];
                }else if(!vis[j][1]&&dis[j][1]<min){
                    k=j;
                    flog=1;
                    min=dis[i][1];
                }
    
            }//cout << 1;
            if(min==inf) break; 
            vis[k][flog] = 1;
            for (int j = 0; j < n; j++) {
                //if (!vis[j]&&map[k][j]<inf) {
                if (map[k][j]!=-1) {
                    if (min + map[k][j] < dis[j][0]) {
                        dis[j][1] = dis[j][0];
                        cnt[j][1] = cnt[j][0];
                        cnt[j][0] = cnt[k][flog];
                        dis[j][0] = min + map[k][j];
                    }
                    else if (min + map[k][j] > dis[j][0] && min + map[k][j] < dis[j][1]) {
                        dis[j][1] = min + map[k][j];
                        cnt[j][1] = cnt[k][flog];
                    }
                    else if (min + map[k][j] == dis[j][0]) {
                        cnt[j][0]+=cnt[k][flog];
                    }
                    else if (min + map[k][j] == dis[j][1]) {
                        cnt[j][1] += cnt[k][flog];
                    }
    
    
                }
    
            }
        }
        cout << dis[e][1] << " " << cnt[e][1];
    }
    int main() {
    
        while (~scanf("%d%d%d%d", &n, &m, &s, &e)) {
            int x, y, z;
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    map[i][j] = -1;
                }
            }
            for (int i = 0; i < m; i++) {
                scanf("%d%d%d", &x, &y, &z);
                map[x][y] = z;
    
            }
    
            dij();
    
        }
        return 0;
    }
  • 相关阅读:
    Apache CXF入门
    C++中关于类型转换的问题讨论
    makefile实例(3)-多个文件实例优化
    makefile实例(2)-多个文件实例
    makefile实例(1)-helloworld
    【原创】Linux下编译链接中常见问题总结
    tcpdump命令
    共享内存基础
    关于TCP/UDP缓存
    TCP/UDP常见问题小结
  • 原文地址:https://www.cnblogs.com/siro/p/11199208.html
Copyright © 2011-2022 走看看