find the mincost route HDU - 1599
阿新 • • 發佈:2018-12-12
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; }