zoukankan      html  css  js  c++  java
  • 666 专题六 最短路练习

    Problem A.Til the Cows Come Home

    d.点N到点1的最短路径

    s.

    c.Dijkstra算法+堆优化

    /*
    Dijkstra算法+堆优化
    使用优先队列优化,复杂度O(E log E)
    使用优先队列优化Dijkstra算法
    复杂度O(E log E)
    注意对vector<Edge>E[MAXN]进行初始化后加边
    */
    #include<iostream>
    #include<stdio.h>
    #include<vector>
    #include<string.h>
    #include<queue>
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    const int MAXN=1024;
    struct qnode{
        int v;
        int c;
        qnode(int _v=0,int _c=0):v(_v),c(_c){}
        bool operator <(const qnode &r)const{
            return c>r.c;
        }
    };
    struct Edge{
        int v,cost;
        Edge(int _v=0,int _cost=0):v(_v),cost(_cost){}
    };
    vector<Edge>E[MAXN];
    bool vis[MAXN];
    int dist[MAXN];
    //点的编号从1开始
    void Dijkstra(int n,int start){
        memset(vis,false,sizeof(vis));
        for(int i=1;i<=n;i++)dist[i]=INF;
        priority_queue<qnode>que;
        while(!que.empty())que.pop();
        dist[start]=0;
        que.push(qnode(start,0));
        qnode tmp;
        while(!que.empty()){
            tmp=que.top();
            que.pop();
            int u=tmp.v;
            if(vis[u])continue;
            vis[u]=true;
            for(int i=0;i<E[u].size();i++){
                int v=E[tmp.v][i].v;
                int cost=E[u][i].cost;
                if(!vis[v]&&dist[v]>dist[u]+cost){
                    dist[v]=dist[u]+cost;
                    que.push(qnode(v,dist[v]));
                }
            }
        }
    }
    void addedge(int u,int v,int w){
        E[u].push_back(Edge(v,w));
    }
    
    int main(){
    
        int T,N;
        int u,v,w;
    
        while(~scanf("%d%d",&T,&N)){
            for(int i=1;i<=N;++i){
                E[i].clear();
            }
    
            for(int i=0;i<T;++i){
                scanf("%d%d%d",&u,&v,&w);
                addedge(u,v,w);
                addedge(v,u,w);
            }
    
            Dijkstra(N,N);
            printf("%d
    ",dist[1]);
        }
    
        return 0;
    }
    View Code

    Problem B.Frogger(不错)

    d.湖中有很多石头,两只青蛙分别位于两块石头上。其中一只青蛙要经过一系列的跳跃,先跳到其他石头上,最后跳到另一只青蛙那里。目的是求出所有路径中最大变长的最小值(就是在到达目的地的路径中,找出青蛙需要跳跃的最大边长的最小的值)。

    s.Dijkstra单源最短路的变形,不是求最短路径了,而是求路径中最大的一条边最小,修改一下代码比较部分就行了。

    c.Dijkstra单源最短路

    /*
    Dijkstra单源最短路
    权值必须是非负
    单源最短路径,Dijkstra算法,邻接矩阵形式,复杂度为O(n^2)
    求出源beg到所有点的最短路径,传入图的顶点数,和邻接矩阵cost[][]
    返回各点的最短路径lowcost[],路径pre[].pre[i]记录beg到i路径上的父结点,pre[beg]=-1
    可更改路径权类型,但是权值必须为非负
    */
    #include<iostream>
    #include<stdio.h>
    #include<math.h>
    using namespace std;
    
    const int MAXN=205;
    #define typec double
    const typec INF=5000000;//防止后面溢出,这个不能太大
    bool vis[MAXN];
    int pre[MAXN];
    void Dijkstra(typec cost[][MAXN],typec lowcost[],int n,int beg){
        for(int i=0;i<n;i++){
            lowcost[i]=INF;vis[i]=false;pre[i]=-1;
        }
        lowcost[beg]=0;
        for(int j=0;j<n;j++){
            int k=-1;
            double Min=INF;
            for(int i=0;i<n;i++)
                if(!vis[i]&&lowcost[i]<Min){
                    Min=lowcost[i];
                    k=i;
                }
            if(k==-1)break;
            vis[k]=true;
            for(int i=0;i<n;i++)
                if(!vis[i]&&lowcost[k]<lowcost[i]&&cost[k][i]<lowcost[i]){
                    lowcost[i]=lowcost[k]>cost[k][i]?lowcost[k]:cost[k][i];
                    pre[i]=k;
                }
        }
    }
    
    int main(){
    
        int n;
        double x[MAXN],y[MAXN];
        double cost[MAXN][MAXN];
        double lowcost[MAXN];
        int C=0;
    
        while(~scanf("%d",&n)){
    
            if(n==0)break;
    
            for(int i=0;i<n;++i){
                scanf("%lf%lf",&x[i],&y[i]);
            }
    
            for(int i=0;i<n;++i){
                for(int j=0;j<n;++j){
                    cost[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
                }
            }
    
            Dijkstra(cost,lowcost,n,0);
    
            printf("Scenario #%d
    ",++C);
            printf("Frog Distance = %.3f
    ",lowcost[1]);
            printf("
    ");
        }
    
        return 0;
    }
    View Code

    Problem C.Heavy Transportation

    d.和上个题相反,求路径中最小的一条边最大

    s.和上个题类似。不过用下面这个堆优化的模板时,注意要修改下优先队列的优先级,这个题是最大值优先。

    c.Dijkstra算法+堆优化

    /*
    Dijkstra算法+堆优化
    使用优先队列优化,复杂度O(E log E)
    使用优先队列优化Dijkstra算法
    复杂度O(E log E)
    注意对vector<Edge>E[MAXN]进行初始化后加边
    */
    #include<iostream>
    #include<stdio.h>
    #include<vector>
    #include<string.h>
    #include<queue>
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    const int MAXN=1024;
    struct qnode{
        int v;
        int c;
        qnode(int _v=0,int _c=0):v(_v),c(_c){}
        bool operator <(const qnode &r)const{
            return c<r.c;
        }
    };
    struct Edge{
        int v,cost;
        Edge(int _v=0,int _cost=0):v(_v),cost(_cost){}
    };
    vector<Edge>E[MAXN];
    bool vis[MAXN];
    int dist[MAXN];
    //点的编号从1开始
    void Dijkstra(int n,int start){
        memset(vis,false,sizeof(vis));
        //for(int i=1;i<=n;i++)dist[i]=INF;
        memset(dist,0,sizeof(dist));//这里不是初始化为INF了
        priority_queue<qnode>que;
        while(!que.empty())que.pop();
        dist[start]=INF;//出发点设为最大
        que.push(qnode(start,INF));
        qnode tmp;
        while(!que.empty()){
            tmp=que.top();
            que.pop();
            int u=tmp.v;
            if(vis[u])continue;
            vis[u]=true;
            for(int i=0;i<E[u].size();i++){
                int v=E[tmp.v][i].v;
                int cost=E[u][i].cost;
                if(!vis[v]&&dist[v]<dist[u]&&dist[v]<cost){
                    dist[v]=dist[u]<cost?dist[u]:cost;
                    que.push(qnode(v,dist[v]));
                }
            }
        }
    }
    void addedge(int u,int v,int w){
        E[u].push_back(Edge(v,w));
    }
    
    int main(){
    
        int T;
        int n,m;
        int u,v,w;
        int C=0;
    
        scanf("%d",&T);
    
        while(T--){
    
            scanf("%d%d",&n,&m);
    
            for(int i=1;i<=n;++i){
                E[i].clear();
            }
    
            for(int i=0;i<m;++i){
                scanf("%d%d%d",&u,&v,&w);
                addedge(u,v,w);
                addedge(v,u,w);
            }
    
            Dijkstra(n,1);
    
            printf("Scenario #%d:
    ",++C);
            printf("%d
    ",dist[n]);
            printf("
    ");
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    Android中GC_EXTERNAL_ALLOC的含义
    Phonegap开发的前后台数据交互
    代码管理工具TortoiseSVN
    14款响应式前端开发框架
    简化工作流程,10款必备的HTML5开发工具
    [C#.net]处理UTF-8文件乱码
    [Oracle]ORA-14400:插入的分区关键字未映射到任何分区
    [网络]10M、100M、1000M网线的水晶头接法
    [Office]Execl取消保护密码
    SLI的相关学习
  • 原文地址:https://www.cnblogs.com/gongpixin/p/5139525.html
Copyright © 2011-2022 走看看