这道题其实就是转化一个模型就可以了。
买了一个另外一个又优惠,其实就相当于在优惠的时候连一条边,因为不可能多买,所以就是建一棵最小生成树。最后因为肯定买了一件物品,要加上最初的单价。
代码:
#include <bits/stdc++.h>
using namespace std;
struct node{
int l , r , w;
};
node e[510000];
int price , n , tot , now , ans;
int fa[5100] , vis[5100][5100];
bool cmp(node &x , node &y){
return x.w < y.w;
}
int find(int x){
if(x == fa[x]) return x;
return fa[x] = find(fa[x]);
}
int main(){
cin >> price >> n;
for(int i = 1; i <= n; i++) fa[i] = i;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++){
int x;
cin >> x;
if(x != 0 && !vis[i][j]){ //去重+为0的时候不建边
vis[i][j] = vis[j][i] = 1;
tot++;
e[tot].l = i , e[tot].r = j , e[tot].w = x;
}
}
sort(e + 1 , e + tot + 1 , cmp);
for(int i = 1; i <= tot; i++){
if(now == n - 1) break;
int x = find(e[i].l) , y = find(e[i].r);
if(x == y) continue;
now++;
ans += min(e[i].w , price); //有可能优惠后更高(坑)
fa[x] = y;
}
cout << ans + price;
return 0;
}