rqnoj-389

来源:互联网 发布:t54原型车数据 编辑:程序博客网 时间:2024/06/07 19:18

先说说floyd的原理,其状态其实是三维的f[i][j][k](只是把k就地滚动了),表示 i-->j 这条路用 1..k 这些点做中转所能取得的最短路,那么根据动规的思想,我们把它分成两类  i-->j用1..k-1做中转   和   i-->j用k做中转   ,用下面这一张图具体解释

dis[][]表示用floyd更新的最短路,而map[][]表示原来的长度
如果我们加上 k 这一状态,那么途中绿色部分就是 i-->j经过1..k-1作中转的最短路,那么现在我们用上 k 这个点我们只需要连上  i-k 和 k-j 就能构成一个环,由于dis[i][j]只用了1..k-1来做中转,而map[i][k]和map[k][j]用了k,所以路径是肯定不会重复的

#include<stdio.h>#include<stdlib.h>#include<string.h>long n,m,i,j,k,MIN;long dp[300][300],cost[300][300];int main(){    //freopen("d:\\test.txt","r",stdin);    scanf("%d%d",&n,&m);    for(i=1;i<=n;++i)        for(j=1;j<=n;++j)            cost[i][j]=0xfffff;    int x,y,c;    for(i=1;i<=m;++i)    {        scanf("%d%d%d",&x,&y,&c);        cost[x][y]=cost[y][x]=c;    }    for(i=1;i<=n;++i)        for(j=1;j<=n;++j)            dp[i][j]=cost[i][j];    MIN=0xfffff;    for(k=1;k<=n;++k)    {        for(i=1;i<k;++i)            for(j=i+1;j<k;++j)                if(MIN>dp[i][j]+cost[i][k]+cost[k][j])                    MIN=dp[i][j]+cost[i][k]+cost[k][j];        for(i=1;i<=n;++i)            for(j=1;j<=n;++j)                if(dp[i][j]>dp[i][k]+dp[k][j])                    dp[i][j]=dp[i][k]+dp[k][j];    }    if(MIN==0xfffff)        printf("He will never come back.\n");    else        printf("%d\n",MIN);    return 0;}


原创粉丝点击