zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    jQuery相关知识点2
    自适应相关知识点1
    jQuery相关知识点1
    执行程序(例如UltraEdit)在WIN7下添加到右键菜单
    std::string 字符串大小写转换(转)
    Mathematica作图
    编写高效代码(大话处理器)
    关于make: *** No rule to make target `clean'. Stop.这个莫名其妙问题的解决方法
    网络编程 tcp udp 时间同步机制 代码
    python_控制台输出带颜色的文字方法
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9408733.html
Copyright © 2011-2022 走看看