• POJ 3268 Silver Cow Party(最短路&Dijkstra)题解


    题意:有n个地点,有m条路,问从所有点走到指定点x再走回去的最短路中的最长路径

    思路:用Floyd超时的,这里用的Dijkstra。

    Dijkstra感觉和Prim和Kruskal的思路很像啊。我们把所有点分为两个集合:S(和源点在同一集合),T(其余点),用dis数组表示每个点到S的最短距离,vis数组记录这个点是否在S中。我们每次找出在T的一个和S距离最短的点,加到S中,这个距离就是他到源点的最短路径(听说能证,我不会证...),然后更新其他点,直到所有点都在S。

    这道题从x走回去很简单,就是单源点最短路,但是从某一点走到x的最短路怎么求?遍历?这里有个很妙的方法,就是转置map,然后我们再求一遍x到每个点的最短路径就行了。

    代码:

    #include<cstdio>
    #include<set>
    #include<cmath>
    #include<stack>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int maxn = 1000+5;
    const int INF = 0x3f3f3f3f;
    int mp[maxn][maxn];
    int dis[maxn];  //和源点集合最短距离
    int vis[maxn];  //1则和源点在同一集合内
    int n,m,x;
    void dijkstra(){
        memset(vis,0,sizeof(vis));
        memset(dis,INF,sizeof(dis));
        dis[x] = 0; //初始化,到自己距离为0
        for(int i = 1;i <= n;i++){
            int Min = INF,k = 0;
            for(int j = 1;j <= n;j++){
                if(!vis[j] && dis[j] < Min){    //找一个和源点集合距离最近的
                    Min = dis[j];
                    k = j;
                }
            }
            vis[k] = 1;
            for(int j = 1;j <= n;j++){  //更新和源点集合距离
                if(dis[j] > dis[k] + mp[k][j]){
                    dis[j] = dis[k] + mp[k][j];
                }
            }
        }
    }
    void transpose(){
        for(int i = 1;i <= n;i++){
            for(int j =  1;j < i;j++){
                swap(mp[i][j],mp[j][i]);
            }
        }
    }
    int ans[maxn];
    int main(){
        while(scanf("%d%d%d",&n,&m,&x) != EOF){
            memset(mp,INF,sizeof(mp));
            for(int i = 0;i < m;i++){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                mp[u][v] = w;
            }
            dijkstra();
            for(int i = 1;i <= n;i++)
                ans[i] = dis[i];
            transpose();
            dijkstra();
            for(int i = 1;i <= n;i++)
                ans[i] += dis[i];
            int Max = 0;
            for(int i = 1;i <= n;i++)
                Max = max(Max,ans[i]);
            printf("%d
    ",Max);
        }
        return 0;
    }
    
  • 相关阅读:
    超宽带技术的定位原理(转载)
    今日学习——2019年4月8日
    解答室内定位技术新方向:蓝牙AoA定位,值得了解 ——概念了解
    LED室内定位算法:RSS,TOA,AOA,TDOA(转载)
    关于值类型、引用类型以及“栈”跟“堆”的关系——转载自菜鸟教程
    华为liteos了解(一)
    物联网的概念
    c语言——字符串
    指针的操作 p*++
    在完成端口中使用GetAcceptExSockaddrs
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9408733.html
Copyright © 2020-2023  润新知