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.\n");
            else
                printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2013-11-30 14:20  galaxy77  阅读(204)  评论(0编辑  收藏  举报