Codeforces 暴力floyd. 暴力floyd
原题链接
简单
作者:
流动的音符
,
2024-10-07 22:57:16
,
所有人可见
,
阅读 4
#pragma GCC optimize(3,"Ofast","inline")
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
#define int long long
#define ld long double
int f[510][510];
int n,m,p,a[510];
const int inf=1e15;
int dist[510][510];//必须联网的房间 最优服务器距离
bool used[510];
int cus[510];//到达服务器最优路
void floyd(){
for(int k=1;k<=n;k++)//k为中点,链接 i,j
for(int i=1;i<=n;i++) {
if(f[k][i]==inf)
continue;
for(int j=1;j<=n;j++){
if(f[k][j]==inf)
continue;
//i,j点的最值
f[i][j]=min({f[i][j],max(f[i][k],f[j][k])});
}
}
}
void solve()
{
cin>>n>>m>>p;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
f[i][j]=inf;
dist[i][j]=inf;
}
for(int i=1;i<=n;i++)
f[i][i]=0,used[i]=0,cus[i]=inf;
for(int i=1;i<=p;i++) cin>>a[i];
while(m--){
int z,y,w;
cin>>z>>y>>w;
f[z][y]=min(f[z][y],w);
f[y][z]=min(f[y][z],w);
}
floyd();
for(int i=1;i<=p;i++){
int s=a[i];
for(int j=1;j<=n;j++){
dist[i][j]=f[s][j];
}
}
vector<int>ans;
for(int i=1;i<=n;i++){//没次增加一个点,枚举找最优点
if(i>p) {ans.push_back(0);continue;}
int now=inf;
int id=0;
for(int j=1;j<=n;j++){
if(used[j]) continue;
int sum=0;
for(int k=1;k<=p;k++){
int s=a[k];
sum+=min(cus[k],dist[k][j]);
}
if(sum<now) {
now=sum;
id=j;
}
}
used[id]=1;
ans.push_back(now);
for(int k=1;k<=p;k++){//新加一个服务器,更新点到服务器的最优距离
cus[k]=min(cus[k],dist[k][id]);
}
}
for(auto x: ans) cout<<x<<" ";
cout<<endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int t; cin>>t;
while(t--)
{
solve();
}
return 0;
}