• hdu 1874 畅通工程续


    最短路径裸题 ,用了dijkstra , Floy  ,   Bellman-Floy   算法实现,纯粹练手

    Dijkstra_数组模拟邻接表_优先队列STL实现 

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <utility>
    #define N 210
    #define M 2020  //有1000条无向边,要转化为两条有向边保存
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef pair<int,int> pii;
    struct edge
    {int u,v,w,next;}e[M];
    int first[N],d[N],done[N];
    int n,m,s,t;
    
    void input()
    {
        memset(first,-1,sizeof(first));
        m*=2;  //m条无向边相当于2*m条有向边处理
        for(int i=0; i<m; i+=2)  //无向图,邻接表,每输入一边无向边相当于有两条有向边
        {
            int u;
            scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
            e[i+1].u=e[i].v;  e[i+1].v=e[i].u; e[i+1].w=e[i].w;
            //先处理第一条有向边<u,v>,即e[i]里面的信息
            u=e[i].u;
            e[i].next=first[u];
            first[u]=i;
            //后处理第二条有向边<v,u>,即e[i+1]里面的信息
            u=e[i+1].u;
            e[i+1].next=first[u];
            first[u]=i+1;
        }
        scanf("%d%d",&s,&t);
    /*
        printf("打印邻接表:\n");
        for(int i=0; i<n; i++)
        {
            printf("%d:",i);
            for(int k=first[i]; k!=-1; k=e[k].next)
            {
                int v=e[k].v , w=e[k].w;
                printf(" %d\\%d",v,w);
            }
            printf("\n");
        }
        printf("************************\n");
    */
        return ;
    }
    void dij_priority_queue()
    {    
        priority_queue< pii,vector<pii>,greater<pii> > q;
        //优先队列需要三个参数,1.元素类型 2.容器类型 3.比较算子
        memset(d,0x3f,sizeof(d));     d[s]=0;
        memset(done,0,sizeof(done));
        q.push(make_pair(d[s],s));  //将一个二元组(d[s],s)放入优先队列
    
        while(!q.empty())
        {
            pii x;
            x=q.top();  q.pop();  //读入优先队列优先级最高的元素并且将其出队
            int u=x.second;     //得到二元组的第二个元素,也就是顶点的标号
            if(done[u])  continue;  //这个顶点已经算得最短路,直接抛弃
            done[u]=1;              //记得标记
            for(int k=first[u]; k!=-1; k=e[k].next)  //遍历u顶点的邻接表
            {
                int v=e[k].v , w=e[k].w ;
                if( d[u]+w < d[v] )   //可以松弛
                {
                    d[v]=d[u]+w;
                    q.push(make_pair(d[v],v));  //松弛成功的入队
                }
            }
        }
    
        if(d[t]==INF) printf("-1\n");
        else          printf("%d\n",d[t]);
        return ;
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            input();
            dij_priority_queue();  //使用优先队列的dij求最短路
        }
        return 0;
    }

     

    Dijkstra算法_邻接矩阵

    //dij算法,单源最短路径
    //注意细节,可能有重边,取最小的那个
    #include <stdio.h>
    #include <string.h>
    #define N 210
    #define INF 1000000000
    int S,V;
    int n,m;
    int g[N][N];
    int cov[N],d[N];
    
    void DIJ()
    {
        int nn,min,k,i;
        
        d[S]=0;
        for(nn=1; nn<n; nn++)  //个数,还要求出源点S到其余所有点的最短路径
        {
            min=INF; k=S;
            for(i=0; i<n; i++)  //扫描所有的点
                if(!cov[i] && d[i]<min)
                {
                    k=i;
                    min=d[i];
                }
            cov[k]=1;
    
            for(i=0; i<n; i++)  //松弛操作
                if(!cov[i] && d[i] > min+g[k][i])
                    d[i]=min+g[k][i];
        }
    }
    int main()
    {
        int i,j,u,v,w;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            memset(cov,0,sizeof(cov));
            for(i=0; i<n; i++)
                for(d[i]=INF,j=0; j<n; j++)
                    g[i][j]=INF;
            for(i=1; i<=m; i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                if(g[u][v] > w) //判断重边
                g[u][v]=g[v][u]=w;
            }
            scanf("%d%d",&S,&V);
            DIJ();
            if(d[V]==INF) printf("-1\n");
            else          printf("%d\n",d[V]);
        }
        return 0;
    }

    Floy算法

    #include <stdio.h>
    #include <string.h>
    #define N  210
    #define INF 1000000000
    int d[N][N];
    int n,m,S,V;
    
    void Floy()
    {
        int i,j,k;
    
        for(k=0; k<n; k++)
            for(i=0; i<n; i++)
                for(j=0; j<n; j++)
                    if(d[i][j] > d[i][k]+d[k][j])
                        d[i][j]=d[i][k]+d[k][j];
        return ;
    }
    
    int main()
    {
        int i,j,u,v,w;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            for(i=0; i<n; i++)
                for(j=0; j<n; j++)
                    if(i==j) d[i][j]=0;
                    else     d[i][j]=INF;
    
            for(i=1; i<=m; i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                if(w<d[u][v])
                    d[u][v]=d[v][u]=w;
            }
            scanf("%d%d",&S,&V);
            Floy();
            if(d[S][V]==INF) printf("-1\n");
            else             printf("%d\n",d[S][V]);
    /*
            for(i=0; i<n; i++)
            {
                for(j=0; j<n; j++)
                    printf("%d ",d[i][j]);
                printf("\n");
            }
    */
         }
        return 0;
    }

    Bellman-Floy算法

    #include <stdio.h>
    #include <string.h>
    #define N 210
    #define INF 1000000000
    int g[N][N],d[N];
    int S,V,n,m;
    
    void Bellman_Floy()
    {
        int nn,i,j;
        d[S]=0;
        for(nn=1; nn<n; nn++) //定点数为n,要做n-1次
            //枚举所有的边i->j ,然后进行松弛操作
            for(i=0; i<n; i++)
                for(j=0; j<n; j++)
                    if( d[j] > d[i]+g[i][j])
                        d[j]=d[i]+g[i][j];
    }
    
    int main()
    {
        int i,j,u,v,w;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            for(i=0; i<n; i++)
                for(d[i]=INF,j=0; j<n; j++)
                    g[i][j]=INF;
    
            for(i=1; i<=m; i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                if(w<g[u][v])
                    g[u][v]=g[v][u]=w;
            }
            scanf("%d%d",&S,&V);
            Bellman_Floy();
            if(d[V]==INF) printf("-1\n");
            else          printf("%d\n",d[V]);
    
        }
        return 0;
    }
  • 相关阅读:
    谷歌Google Chrome浏览器打开新的标签页设置指定固定网址
    Vue子组件和父组件、子组件调用父组件的方法、父组件调用子组件方法、子组件与父组件间的传值
    查询Linux服务器出口IP、curl命令查询Linux公网出口IP、Windows服务器查询出口IP
    mysql查询是对字段进行补0操作,可用于树状结构整体排序
    mysql批量update更新,mybatis中批量更新操作
    CentOS 6.8下网卡配置、桥接模式和NAT连接模式、VMware虚拟机克隆网卡配置
    杂七杂八
    解决SpringMVC拦截器中Request数据只能读取一次的问题
    Redis安装教程及可视化工具RedisDesktopManager下载安装
    JAVA获取客户端请求的当前网络ip地址(附:Nginx反向代理后获取客户端请求的真实IP)
  • 原文地址:https://www.cnblogs.com/scau20110726/p/2755697.html
Copyright © 2020-2023  润新知