zoukankan      html  css  js  c++  java
  • hdu 1874 畅通工程续(迪杰斯特拉优先队列,floyd,spfa)

    畅通工程续

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 49963    Accepted Submission(s): 18624


    Problem Description
    某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。

    现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
     

    Input
    本题目包含多组数据,请处理到文件结束。
    每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
    接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
    再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。
     

    Output
    对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1.
     

    Sample Input
    3 3 0 1 1 0 2 3 1 2 1 0 2 3 1 0 1 1 1 2
     

    Sample Output
    2 -1
    //迪杰斯特拉
    #include<queue>
    #include<stack>
    #include<math.h>
    #include<stdio.h>
    #include<numeric>//STL数值算法头文件
    #include<stdlib.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    #include<functional>//模板类头文件
    using namespace std;
    
    const int INF=1e9+7;
    const int maxn=100+10;
    
    int n,m,st,ed;
    int par[maxn];
    int vis[maxn];
    int tu[maxn][maxn];
    
    int dijkstra(int st,int ed)
    {
        int i,j,k,minn;
        memset(vis,0,sizeof(vis));
        for(i=0; i<n; i++)
            par[i]=tu[st][i];
        vis[st]=1;
        par[st]=0;
        for(i=1; i<n; i++)
        {
            minn=INF;
            for(j=0; j<n; j++)
            {
                if(!vis[j]&&minn>par[j])
                {
                    k=j;
                    minn=par[j];
                }
            }
            vis[k]=1;
            for(j=0; j<n; j++)
            {
                if(!vis[j]&&par[j]>par[k]+tu[k][j])
                {
                    par[j]=par[k]+tu[k][j];
                }
            }
        }
    }
    
    int main()
    {
        while(~scanf("%d %d",&n,&m))
        {
            int i,j,u,v,w;
            memset(tu,0,sizeof(tu));
            for(i=0; i<n; i++)
            {
                for(j=0; j<n; j++)
                {
                    tu[i][j]=i==j?0:INF;
                }
            }
            while(m--)
            {
                scanf("%d %d %d",&u,&v,&w);
                if(tu[u][v]>w)
                    tu[u][v]=tu[v][u]=w;
            }
            scanf("%d %d",&st,&ed);
            dijkstra(st,ed);
            printf("%d
    ",par[ed]==INF?-1:par[ed]);
        }
        return 0;
    }
    
    
    //Floyd弗洛伊德
    #include <cstdio>
    #include <cstring>
    using namespace std;
    #define INF 10000
    const int maxn = 201;
    int tu[maxn][maxn];
    
    int main()
    {
        int n, m;
        while (scanf("%d%d", &n, &m) != EOF)
        {
            memset (tu, INF, sizeof(tu));
            int u, v, w;
            for (int i = 0; i < m; i++)
            {
                scanf("%d%d%d", &u, &v, &w);
                if (tu[u][v] > w)
                    tu[u][v] = tu[v][u] = w;
            }
            for (int i = 0; i < n ; i++)
                tu[i][i] = 0;
            for (int k = 0; k < n; k++)
                for (int i = 0; i < n; i++)
                    for (int j = 0; j < n; j++)
                    {
                        if (tu[i][k] + tu[k][j] < tu[i][j])
                            tu[i][j] = tu[j][i] = tu[i][k] + tu[k][j];
                    }
            scanf("%d%d", &u, &v);
            if (tu[u][v] < INF)
                printf("%d
    ", tu[u][v]);
            else
                printf("-1
    ");
        }
        return 0;
    }
    //#include<queue>
    //#include<stack>
    //#include<vector>
    //#include<math.h>
    //#include<stdio.h>
    //#include<numeric>//STL数值算法头文件
    //#include<stdlib.h>
    //#include<string.h>
    //#include<iostream>
    //#include<algorithm>
    //#include<functional>//模板类头文件
    //using namespace std;
    //
    //const int INF=1e9+7;
    //const int maxn=205;
    //vector<pair<int,int> >E[maxn];
    //int d[maxn],inq[maxn];//inq数组表示是否在队列中,d数组表示起点到当前点的距离
    //
    //void init()
    //{
    //    for(int i=0; i<maxn; i++) E[i].clear();
    //    for(int i=0; i<maxn; i++) inq[i]=0;
    //    for(int i=0; i<maxn; i++) d[i]=INF;
    //}
    //
    //int n,m;
    //int main()
    //{
    //    while(cin>>n>>m)
    //    {
    //        int i,j;
    //        init();
    //        for(i=0; i<m; i++)
    //        {
    //            int x,y,z;
    //            scanf("%d %d %d",&x,&y,&z);
    //            E[x].push_back(make_pair(y,z));
    //            E[y].push_back(make_pair(x,z));
    //        }
    //        int s,t;
    //        scanf("%d %d",&s,&t);
    //        queue<int>q;
    //        q.push(s),d[s]=0,inq[s]=1;
    //        while(!q.empty())
    //        {
    //            int now=q.front();
    //            q.pop();
    //            inq[now]=0;
    //            for(int i=0; i<E[now].size(); i++)
    //            {
    //                int v=E[now][i].first;
    //                if(d[v]>d[now]+E[now][i].second)
    //                {
    //                    d[v]=d[now]+E[now][i].second;
    //                    if(inq[v]) continue;
    //                    inq[v]=1;
    //                    q.push(v);
    //                }
    //            }
    //        }
    //        if(d[t]==INF) printf("-1
    ");
    //        else printf("%d
    ",d[t]);
    //    }
    //    return 0;
    //}
    
    
    
    
    //"单源最短路"迪杰斯特拉,优先队列
    //(m+n)*log(n)的复杂度
    //通过中间点来松弛源点到其余各顶点的路径
    #include<queue>
    #include<stack>
    #include<vector>
    #include<math.h>
    #include<stdio.h>
    #include<numeric>//STL数值算法头文件
    #include<stdlib.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    #include<functional>//模板类头文件
    using namespace std;
    
    const int INF=1e9+7;
    const int maxn=205;
    vector<pair<int,int> >E[maxn];
    int d[maxn];//d数组表示起点到当前点的距离
    
    void init()
    {
        for(int i=0; i<maxn; i++) E[i].clear();
        for(int i=0; i<maxn; i++) d[i]=INF;
    }
    
    int n,m;
    int main()
    {
        while(cin>>n>>m)
        {
            int i,j;
            init();
            for(i=0; i<m; i++)
            {
                int x,y,z;
                scanf("%d %d %d",&x,&y,&z);
                E[x].push_back(make_pair(y,z));
                E[y].push_back(make_pair(x,z));
            }
            int s,t;
            scanf("%d %d",&s,&t);
            priority_queue<pair<int,int> >q;
            d[s]=0;
            q.push(make_pair(-d[s],s));
            while(!q.empty())
            {
                int now=q.top().second;
                q.pop();
                for(int i=0; i<E[now].size(); i++)
                {
                    int v=E[now][i].first;
                    if(d[v]>d[now]+E[now][i].second)
                    {
                        d[v]=d[now]+E[now][i].second;
                        q.push(make_pair(-d[v],v));
                    }
                }
            }
            if(d[t]==INF) printf("-1
    ");
            else printf("%d
    ",d[t]);
        }
        return 0;
    }
    












    //时间复杂度最低
    #include<map>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<math.h>
    #include<cstdio>
    #include<sstream>
    #include<numeric>//STL数值算法头文件
    #include<stdlib.h>
    #include <ctype.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    #include<functional>//模板类头文件
    using namespace std;
    
    typedef long long ll;
    const int maxn=1100;
    const int INF=0x3f3f3f3f;
    
    int n,m,dis[maxn],head[maxn],cnt[maxn],len;
    bool vis[maxn];
    
    struct edge
    {
        int to,val,next;
    } e[maxn];
    
    void add(int from,int to,int  val)
    {
        e[len].to=to;
        e[len].val=val;
        e[len].next=head[from];
        head[from]=len++;
    }
    bool spfa(int s,int t)
    {
        memset(cnt,0,sizeof(cnt));
        memset(vis,0,sizeof(vis));
        for(int i=0; i<n; i++)
            dis[i]=INF;
    
        queue<int> q;
        q.push(s);
        cnt[s]++;
        vis[s]=true;
        dis[s]=0;
        while(!q.empty())
        {
            int cur=q.front();
            q.pop();
            vis[cur]=false;
            for(int i=head[cur]; i!=-1; i=e[i].next)
            {
                int id=e[i].to;
                if(dis[id] > dis[cur]+e[i].val)
                {
                    dis[id] = dis[cur] + e[i].val;
                    if(!vis[id])
                    {
                        cnt[id]++;
                        vis[id]=true;
                        if(cnt[cur]>n) return false;
                        q.push(id);
                    }
                }
            }
        }
        return true;
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            len=0;
            memset(head,-1,sizeof(head));
    
            for(int i=0; i<m; i++)
            {
                int from,to,val;
                scanf("%d%d%d",&from,&to,&val);
                add(from,to,val);
                add(to,from,val);
            }
            
            int s,t;
            scanf("%d%d",&s,&t);
            spfa(s,t);
            if(spfa(s,t)&&dis[t]!=INF) printf("%d
    ",dis[t]);
            else printf("-1
    ");
        }
        return 0;
    }
    


    
    

    
       
    
  • 相关阅读:
    【开发者笔记】C#连接mysql问题记录
    【开发者笔记】揣摩Spring-ioc初探,ioc是不是单例?
    【开发者笔记】c# 调用java代码
    【数据库乱码】记录一下数据库乱码问题
    字符函数
    单行函数和多行函数
    rownum和rowid伪列
    排序子句
    单引号的转义
    逻辑运算符
  • 原文地址:https://www.cnblogs.com/nyist-xsk/p/7264872.html
Copyright © 2011-2022 走看看