洛谷 P1194 买礼物 最小生成树--但有小坑
这个题我们模拟题目一下就会发现是一道最小生成树的题目,
我们通常会想到:ans=最小生成树的长度+单买一件商品a
注意点1:如果 KI,J=0,那么表示这两样东西之间不会导致优惠。也就是没有边
注意点2:注意 KI,J 可能大于 A。这就意味着我们需要 min(ans,a*b)一下
不过还有一个坑点(我忽略了):可能不连通(也就是没有最小生成树),这种情况就用现有的(假)最小生成树+要单买的商品+a
const int N = 500 + 10,T = 20;
LL a,b;
struct Edge
{
LL a,b,w;
bool operator< (const Edge& t) const
{
return w < t.w;
}
};
int p[N];
vector<Edge> edges;
LL find(LL x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
void solve()
{
cin >> a >> b;
for (int i = 1;i <= b;i ++)
for (int j = 1;j <= b;j ++)
{
LL w; cin >> w;
if (i != j && !w) continue;
edges.push_back({i,j,w});
}
sort(edges.begin(),edges.end());
for (int i = 1;i <= b;i ++) p[i] = i;
LL ans = 0;
LL cnt = 0;
for (auto &[a,b,w] : edges)
{
if (find(a) == find(b)) continue;
ans += w;
p[find(a)] = find(b);
cnt ++;
}
if (cnt == b - 1)//联通
cout << min(ans + a,a * b) << endl;
else//不连通
cout << min(ans + (b - 1 - cnt) * a + a,a * b) << endl;
}