解題報告:
要通過此題就要明白 flo
yedfloyed
floyed
演算法原理及其每步的含義。
for
(int k=
1;k<=n;k++)}
} 其本質就是動態規劃
k作為階段必須置於最外層,i,j作為附加狀態置於內層
mp可以理解為 經過若干個編號不超過k的節點從i到j的最短路,進而轉化為兩個子問題:
1.經過給若干個編號不超過k-
1的節點從i到j最短路
2.節點i經過k節點到j節點
因此: mp
=min
(mp1,i,j>
, mp
1,i,k>
+ mp
1,k,j>
) 再通滾動陣列優化得到 mp
在列舉每次的ki時,我們就已經求出來 1
~k-1之間的最短路。
回到本題求最小環:
假設存在一條最小環 u−v
−k−u
u-v-k-u
u−v−k−
u,既然是最小環,當拆掉 u−v
u-vu−
v時,v−k
−uv-k-u
v−k−
u就是(u,
v)(u,v)
(u,v
)最短路。
再回到前面floyed演算法每次列舉 k
ik_i
ki 的時候我們就已經求出來1~k-1之間的最短路,前 k−1
k-1k−
1 個的點不包含 k
kk 節點且它們之間的最短路徑之間也不經過 k
kk 節點。
從前 k−1
k-1k−
1 個點中取兩點 i,j
i,ji,
j ,(i,
j)(i,j)
(i,j
) 之間的最短路已經求得且不經過節點 k
kk,再跟據floyed原理以k為中間節點進行更新得到最小環 i−j
−k−i
i-j-k-i
i−j−k−
i。
#include
#define ll long long
#define pii pair
#define all(x) x.begin(),x.end()
#define wp(x) write(x),putchar('\n')
#define wpl(x) write(x),putchar(' ')
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const
int maxn =
2e5+5;
inline
intread()
while
(ch >=
'0'&& ch <=
'9')
return s * f;
}inline
void
write
(ll x)
int mp[
105]
[105
],g[
105]
[105];
intmain()
int ans=
1e8;
for(
int k=
1;k<=n;k++)}
for(
int i=
1;i<=n;i++)}
}if(ans==
1e8)
printf
("no solution.\n");
else
printf
("%d\n"
,ans);}
return0;
}
觀光旅遊 Floyed 最小環
time limit 20000ms memory limit 65536k total submit 292 accepted 144 case time limit 2000ms description 在桑給巴爾島的ade lton adelton adelto n城鎮上有乙個旅遊機構。它們決...
最小環問題
floyd找最小環 模板 mp i j mp i j mp i j 記錄i ii到j jj的最短路,dis i j dis i j dis i j 代表原始圖的頂點間的關係 非i ii到j jj的最短路 ll ans inf ans為最小環的長度 for int k 1 k n k for int ...
模板 最小環
題意 在乙個無向圖里找出乙個由至少三個點組成環,使得環上邊的權值和最小。首先,由於我們的環至少要有三個點,我們就考慮每次列舉環的兩個端點 不關心端點中間有多少個點 再用另外乙個點將這兩個端點連線起來,那麼就一定能夠保證形成乙個至少有三個點的環。想一想,這樣是不是有什麼問題?如果用於連線的點本來就在環...