题解:P14362 [CSP-S 2025] 道路修复 / road(民间数据)
考虑到对于
#include<bits/stdc++.h>
using namespace std;
int n,m,k,f[10015],c[15];
struct node{
int u,v,w;
}s[1000005],nw[10005],init[15][10005],t[2][120005];
long long ans=0;
int getf(int x){return (x==f[x])?x:f[x]=getf(f[x]);}
int main(){
cin>>n>>m>>k;
for(int i=0;i<m;i++)cin>>s[i].u>>s[i].v>>s[i].w;
sort(s,s+m,[](node x,node y){return x.w<y.w;});
int tmp=0,p=0;
for(int i=1;i<=n;i++)f[i]=i;
while(tmp<n-1){
int fx=getf(s[p].u),fy=getf(s[p].v);
if(fx!=fy){
f[fx]=fy;
ans+=s[p].w;
tmp++;
nw[tmp]=s[p];
}
p++;
}
for(int i=1;i<=k;i++){cin>>c[i];for(int j=1;j<=n;j++){cin>>init[i][j].w;init[i][j].u=n+i;init[i][j].v=j;}sort(init[i]+1,init[i]+1+n,[](node x,node y){return x.w<y.w;});}
for(int i=1;i<(1<<k);i++){
for(int j=1;j<=n+k;j++)f[j]=j;
int sum=0,id=0;
int num=n+__builtin_popcount(i),cnt=0,kk=1;
long long anss=0;
for(int j=1;j<n;j++)t[id][++sum]=nw[j];
for(int j=1;j<=k;j++){
if(!((1<<(j-1))&i))continue;
anss+=c[j];
id^=1;
int l=1,r=1,summ=0;
while(l<=sum&&r<=n){
if(t[id^1][l].w<=init[j][r].w)t[id][++summ]=t[id^1][l++];
else t[id][++summ]=init[j][r++];
}
while(l<=sum)t[id][++summ]=t[id^1][l++];
while(r<=n)t[id][++summ]=init[j][r++];
sum=summ;
}
while(cnt<num-1){
int fx=getf(t[id][kk].u),fy=getf(t[id][kk].v);
if(fx!=fy){
f[fx]=fy;
anss+=t[id][kk].w;
cnt++;
}
kk++;
}
ans=min(ans,anss);
}
cout<<ans;
return 0;
}