zoukankan      html  css  js  c++  java
  • poj 3268 最短路

    ***题意:在x这个点有个聚会,其他的点要到x这个点,然后再会自己原始的点,求一来一回最大的那个距离

    做法:两边dijstra算法,因为是单向图,要注意更新顺序***

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    
    using namespace std;
    #define N 1010
    #define INF 0x3f3f3f3f
    
    int maps[N][N];
    int n, m, x;
    int dist1[N], dist2[N], vis[N];
    
    void Init()
    {
        for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
        maps[i][j]=i==j ? 0 : INF;
    }
    
    void dij()
    {
        for(int i=1; i<=n; i++)
            dist1[i]=maps[i][x];
    
        memset(vis, 0, sizeof(vis));
        vis[x]=1;
        for(int i=1; i<=n; i++)
        {
            int Min=INF, index=-1;
            for(int j=1; j<=n; j++)
            {
                if(!vis[j]&&dist1[j]<Min)
                {
                    Min=dist1[j];
                    index=j;
                }
            }
            if(index==-1) break;
            vis[index]=1;
            for(int j=1; j<=n; j++)
            {
                if(!vis[j]&&dist1[j]>maps[j][index]+dist1[index])
                    dist1[j]=maps[j][index]+dist1[index];
            }
        }
        for(int i=1; i<=n; i++)
            dist2[i]=maps[x][i];
    
        memset(vis, 0, sizeof(vis));
        vis[x]=1;
        for(int i=1; i<=n; i++)
        {
            int Min=INF, index=-1;
            for(int j=1; j<=n; j++)
            {
                if(!vis[j]&&dist2[j]<Min)
                {
                    Min=dist2[j];
                    index=j;
                }
            }
            if(index==-1) break;
            vis[index]=1;
            for(int j=1; j<=n; j++)
            {
                if(!vis[j]&&dist2[j]>dist2[index]+maps[index][j])
                    dist2[j]=dist2[index]+maps[index][j];
            }
        }
    }
    
    int main()
    {
        while(~scanf("%d%d%d", &n, &m, &x))
        {
            Init();
            int u, v, len;
            for(int i=1; i<=m; i++)
            {
                scanf("%d%d%d", &u, &v, &len);
                maps[u][v]=min(len, maps[u][v]);
            }
            dij();
    
            int ans=-1;
    
            for(int i=1; i<=n; i++)
            {
                if(dist1[i]+dist2[i]>ans)
                    ans=dist1[i]+dist2[i];
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code

     ***两遍spfa,第二次的spfa要使用开始建的反向图,建的反向图也就是以x为如点,dist1里存就是其他店到x的距离***

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    
    using namespace std;
    #define N 101000
    #define INF 0x3f3f3f3f
    
    int n, m, x;
    int dist[N], head[N], dist1[N], head1[N], vis[N], k, k1;
    
    struct node
    {
        int v, len, next;
    } a[N], b[N];
    
    void add(int u, int v, int len)
    {
        a[k].v=v;
        a[k].len=len;
        a[k].next=head[u];
        head[u]=k++;
    }
    
    void add1(int u, int v, int len)
    {
        b[k1].v=v;
        b[k1].len=len;
        b[k1].next=head1[u];
        head1[u]=k1++;
    }
    
    int spfa()
    {
        queue<int> q;
        q.push(x);
        dist[x]=0;
        vis[x]=1;
    
        while(!q.empty())
        {
            int t=q.front();
            q.pop();
            vis[t]=0;
            for(int i=head[t]; i!=-1; i=a[i].next)
            {
                int v=a[i].v;
                if(dist[v]>dist[t]+a[i].len)
                {
                    dist[v]=dist[t]+a[i].len;
                    if(!vis[v])
                    {
                        vis[v]=1;
                        q.push(v);
                    }
                }
            }
        }
        memset(vis, 0, sizeof(vis));
        queue<int> Q;
        Q.push(x);
        dist1[x]=0;
        vis[x]=1;
    
        while(!Q.empty())
        {
            int t=Q.front();
            Q.pop();
            vis[t]=0;
            for(int i=head1[t]; i!=-1; i=b[i].next)
            {
                int v=b[i].v;
                if(dist1[v]>dist1[t]+b[i].len)
                {
                    dist1[v]=dist1[t]+b[i].len;
                    if(!vis[v])
                    {
                        vis[v]=1;
                        Q.push(v);
                    }
                }
            }
        }
        int ans=-1;
        for(int i=1; i<=n; i++)
        {
            if(ans<dist[i]+dist1[i]&&dist[i]!=INF&&dist1[i]!=INF)
                ans=dist[i]+dist1[i];
        }
        return ans;
    }
    
    int main()
    {
        int u, v, len;
        while(~scanf("%d%d%d", &n, &m, &x))
        {
            memset(dist, INF, sizeof(dist));
            memset(dist1, INF, sizeof(dist1));
            memset(head, -1, sizeof(head));
            memset(head1, -1, sizeof(head1));
            memset(vis, 0, sizeof(vis));
            k=k1=1;
            for(int i=1; i<=m; i++)
            {
                scanf("%d%d%d", &u, &v, &len);
                add(u, v, len);
                add1(v, u, len);
            }
            int ans=spfa();
    
            printf("%d
    ", ans);
        }
        return 0;
    }
     
    View Code
  • 相关阅读:
    Jquery 学习一
    响应式设计
    微信开发一
    Ajax 技术二
    Ajax 技术一
    SVN版本控制软件
    正则表达式概述
    编写小游戏:贪吃蛇
    POJ 3356 AGTC(DP-最小编辑距离)
    算法模板の字符串处理
  • 原文地址:https://www.cnblogs.com/9968jie/p/5688293.html
Copyright © 2011-2022 走看看