zoukankan      html  css  js  c++  java
  • hdu 1599 find the mincost route floyd

    hdu 1599 find the mincost route

    http://acm.hdu.edu.cn/showproblem.php?pid=1599

    【题意】:在一个无向图中找一个 至少有三个不同点的环 而且花费最少

    **********************************************************

    之前学floyd的时候并没有很认真的去理解那个代码这次写的时候 随手就写出了

    for(i=1;i<=n;i++)
       for(j=1;j<=n;j++)
           for(u=1;u<=n;u++)
                  if(d[i][j]>d[i][u]+d[u][j])
                     d[i][j]>d[i][u]+d[u][j];

    这样的代码 但是后来仔细想想 这样子不行 要求i到j的最短路的时候 先赋初值 他们有边的话就赋为边值没有的话就赋为最大值 然后就是dp 的过程了。

    一次一次的用 点k( k从1---->n) 去更新的d[i][j]的值

    if(d[i][j]>d[i][k]+d[k][j])
           d[i][j]=d[i][k]+d[k][j];//i到j 要经过k点

    更新完后的意思就是 点i到点j 经过的点的编号不超过k的最短路径。(不可能经过>k 的点)

    如果像之前那样写的话 就太早的 d[i][j]的值确定下来了 (k变化一轮就直接定下来了)
    更小的d[i][k]和 d[k][j] 真正算出来了之后 d[i][j]就改变不了了 所以这样是错误的
    代码如下:
    for(u=1;u<=n;u++)
        for(i=1;i<=n;i++)
           for(j=1;j<=n;j++)
               if(d[i][j]>d[i][u]+d[u][j])
                     d[i][j]>d[i][u]+d[u][j];
         

    【注意 】:有重边


    /*



    */
    #include<iostream> #include<stdio.h> #include<string.h> #define INF 100000000 using namespace std; int d[102][102],n,count[102][102],w[102][102]; //i到j 的最短路 int floyd() { int ans=INF,i,j,u; for(u=1;u<=n;u++) { for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(i!=j&&j!=u&&u!=i&&d[i][j]<INF&&w[i][u]<INF&&w[u][j]<INF&&ans>d[i][j]+w[i][u]+w[u][j]) ans=d[i][j]+w[i][u]+w[u][j];

    //这里 (i!=j&&j!=u&&u!=i 是为了 保证i-->j的路经过的点不同 注意 这两个for 要写在下面两个for的前面 因为下面两个for求的是中间的点不大于k的最短路径(就称为d[i][j](k)吧)
    //在这里只算出了(d[i][j](k-1)  路径里只包含 <k 的一些点)  这样 路径i---->j 再加上边i,k 和边k,j 就 构成了一个环了

    for(i=1;i<=n;i++)
                for(j=1;j<=n;j++)            
                    if(d[i][j]>d[i][u]+d[u][j])
                        d[i][j]=d[i][u]+d[u][j];
    
        }
        return ans;
    }
    
    int main()
    {
        int i,j,m,t,k,a,b,c;
        while(~scanf("%d%d",&n,&m))
        {    
            for(i=1;i<=n;i++)
                for(j=1;j<=n;j++)
                {
                    if(i==j)
                        w[i][j]=d[i][j]=0;
                    else
                         w[i][j]=d[i][j]=INF;
                }
                for(i=0;i<m;i++)
                {
                    scanf("%d%d%d",&a,&b,&c);
                    if(c>d[a][b])
                        continue;
    
                    d[a][b]=d[b][a]=w[a][b]=w[b][a]=c;
                }
                int ans=floyd();
                if(ans==INF)
                    printf("It's impossible.
    ");
                else
                    printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    线段树 BZOJ1858 [Scoi2010]序列操作
    dfs序+线段树 BZOJ3252 攻略
    线段树 BZOJ3888 [Usaco2015 Jan]Stampede
    线段树 BZOJ1798 [Ahoi2009]Seq 维护序列seq
    大坑【持续更新……】
    LCA树剖法模板
    Tarjan-LCA HDU2586 How far away ?
    动态规划 洛谷P2401 不等数列
    搜索 洛谷P2530 [SHOI2001]化工厂装箱员
    动态规划 洛谷P1077 摆花
  • 原文地址:https://www.cnblogs.com/assult/p/3450957.html
Copyright © 2011-2022 走看看