洛谷 P6464 [傳智杯 #2 決賽] 傳送門

台州第一深情發表於2024-07-09

透過便利每兩個點之間的傳送門,再便利一次其他點與傳送點的路長度,沒路的情況是最大值不會考慮,有路就取經過傳送門和原本最短路的最小值

/* 台州第一深情 */

include <bits/stdc++.h>

using namespace std;
using i64 = long;
using ll = long long;
typedef pair<int, int> PII;
const int N = 105 + 5;
const int M = 1e6;
ll a[N][N], b[M];
int n, m;
void build()
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (i == j)
{
a[i][j] = 0;
}
else
{
a[i][j] = 1e7;//模板,根據題目定義最大值
}
}
}
}
void floyd()
{
for (int tiao = 1; tiao <= n; tiao++)
{
for (int from = 1; from <= n; from++)
{
for (int to = 1; to <= n; to++)
{
a[from][to] = min(a[from][tiao] + a[tiao][to], a[from][to]);
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
build();
for (int i = 1; i <= m; i++)
{
int from, to, w;
cin >> from >> to >> w;
a[from][to] = w;
a[to][from] = w;//無向圖,存雙邊
}
ll ans = INT_MAX;
floyd();//先確定正常情況下的最小值
for (int i = 1; i < n; i++)
{
for (int j = i + 1; j <= n; j++)//i,j是假設從哪個點到哪個點有傳送門
{
ll p = 0;
for (int i1 = 1; i1 < n; i1++)//每確定一個傳送門都進行一次floyd,便利查詢最小值
{
for (int j1 = i1 + 1; j1 <= n; j1++)
{
if (i1 != i || j1 != j)
{
p += min(a[i1][j1], min(a[i1][i] + a[j][j1], a[i1][j] + a[i][j1]));//便利每個點與傳送點是否有路,如果有的話就判斷一下經過傳送門到目標點是不是會更短
}
}
}
ans = min(ans, p);//取小
}
}
cout << ans << "\n";

return 0;

}

相關文章