前言
赛时只拿到了$ kruskal$板子的 \(A\)性质的 \(32pts\),真正唐完,,,,
切入
首先我们可以一眼顶针看出这是一道最小生成树的题,然后发现\(K\leq10\),可以想到直接暴力枚举\(2^k\)次的不同排列,然后跑一遍\(kruskal\),但是每一次枚举都需要暴力地建一次图,发现重复贡献太多,故考虑优化
优化
先对给出的原边和村庄的边建图,然后根据枚举的条件去封锁没有城市化改造的村庄的边,时间复杂度应该是\(O(2^km+2^kkn)\),其实这道题虽说是蓝但也还挺好想的,对于我的难点来说是不会代码上的实现,导致场上浪费了大量的时间还是打不出来,码力还是太弱了啊......
AC Code
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define endll " "
#define fre(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
#define pii pair<int,int>
#define pb push_back
#define eb emplace_back
#define it inline int
#define iv inline void
#define ib inline bool
#define sakura_no_uta return 0
using namespace std;
const int MAXN=10000050;
const int INF=0x3f3f3f3f3f3f3f3f;
const int MOD=998244353;
it gcd(int x,int y) {return y==0?x:gcd(y,x%y);}
it lcm(int x,int y) {return y/gcd(x,y)*x;}
it max(int x,int y) {return x>y?x:y;}
it min(int x,int y) {return x<y?x:y;}
it ksm(int x,int m,int mod)
{int res=1,bas=x%mod;while(m){if(m&1)res=(res*bas)%mod;bas=(bas*bas)%mod;m >>= 1;}return res;
}
int n,m,l,r,u,v,w,cnt,tot,ans=INF,cnt1,cnt2,cnt3,lim,T,head[MAXN],k,a[11][MAXN],c[MAXN],fa[MAXN],val;
bool vis[11];
it find(int x)
{if(x==fa[x])return x;return fa[x]=find(fa[x]);
}
struct edge
{int fr,to,w;
}e[MAXN];
ib cmp(edge x,edge y)
{return x.w<y.w;
}
iv add_edge(int u,int v,int w)
{e[++tot].fr=u;e[tot].to=v;e[tot].w=w;
}
it calc(int cnt,int tot)
{int sum=cnt1=0;for(int i=1;i<=tot;i++){if((e[i].fr>n&&!vis[e[i].fr-n]) || (e[i].to>n&&!vis[e[i].to-n]))continue;int uu=find(e[i].fr),vv=find(e[i].to);if(uu!=vv){fa[uu]=vv;sum+=e[i].w;cnt1++;if(cnt1==n-1+cnt)break;}}return sum;
}
iv solve()
{lim=1<<k;for(int i=0;i<lim;i++){memset(vis,0,sizeof(vis));cnt=val=0;for(int j=1;j<=k;j++){if((1<<(j-1))&i){val+=c[j];vis[j]=1;++cnt;}}for(int i=1;i<=n+k;i++)fa[i]=i;ans=min(ans,val+calc(cnt,tot));}
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin >> n >> m >> k;for(int i=1;i<=m;i++){cin >> u >> v >> w;add_edge(u,v,w);}for(int i=1;i<=k;i++){cin >> c[i];for(int j=1;j<=n;j++){cin >> a[i][j];add_edge(n+i,j,a[i][j]);}}sort(e+1,e+tot+1,cmp);solve();cout<<ans;sakura_no_uta;
}