1. 程式人生 > >find the mincost route HDU - 1599

find the mincost route HDU - 1599

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

floyd求最小環問題 有向圖的話 跑一遍模板然後n^2掃一遍就好 但是無向圖不能這樣無腦搞 比如三階完全圖 邊權都相等 那就不存在鬆弛了 明明有環但是判不出 想通過記錄最小次小值來搞又會出現重點問題 比如題目第二個樣例 dis[1][3]=2 dis[3][2]=1=>dis[1][2]=3 這樣本來沒環給判出環了

最外層迴圈到k的話 說明[1,k-1]都已經發揮了鬆弛作用 也就是說當前任意兩點之間被鬆弛的最短距離 都是由[1,k-1]確定的 與[k,n]無關 這樣可以列舉[k,n]來通過e[i][k]+e[k][j]+dis[i][j](i,j<k)來找出最小環 但是[k+1,n]目前可以確定的環之後可定會被算上 只用k這個點掃一遍就完事了

 

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1000000000;
const int maxn=1e2+10;

ll e[maxn][maxn],dis[maxn][maxn];
int n,m;

ll floyd()
{
    ll res;
    int i,j,k;
    res=N;
    for(k=1;k<=n;k++){
        for(i=1;i<=k-1;i++){
            for(j=i+1;j<=k-1;j++){
                res=min(res,dis[i][j]+e[i][k]+e[k][j]);
            }
        }
        for(i=1;i<=n;i++){
            for(j=1;j<=n;j++){
                dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
            }
        }
    }
    return res;
}

int main()
{
    ll ans,w;
    int i,j,u,v;
    while(scanf("%d%d",&n,&m)!=EOF){
        for(i=1;i<=n;i++){
            for(j=1;j<=n;j++){
                if(i==j) e[i][j]=0;
                else e[i][j]=N;
            }
        }
        while(m--){
            scanf("%d%d%lld",&u,&v,&w);
            e[u][v]=min(e[u][v],w);
            e[v][u]=min(e[v][u],w);
        }
        for(i=1;i<=n;i++){
            for(j=1;j<=n;j++){
                dis[i][j]=e[i][j];
            }
        }
        ans=floyd();
        if(ans==N) printf("It's impossible.\n");
        else printf("%lld\n",ans);
    }
    return 0;
}