http://acm.hdu.edu.cn/showproblem.php?pid=4313
Kruskal
对于一条边的两个点都有机器的情况下,直接毁掉这条路,即加上这条边的权值
否则 把没有机器人的点归到有机器人的点集合内,将有机器人的点当作父节点
把边的权值按大到小排序
因为 在合并的过程中 逐渐有了两个机器城市的关系,到后面权值小的边时可以毁掉小权值的边从而达到不让他们互通的作用
才能达到最小
可以画个图更加加深理解
#include <bits/stdc++.h>
#define repu(i,s,e) for(int i = s;i <= e; ++i)
#define repd(i,s,e) for(int i = s;i >= e; --i)
#define pb push_back
#define emb emplace_back
#define mst(arr, v) memset(arr, v, sizeof(arr))
#define close_ios ios::sync_with_stdio(false)
#define close_cin cin.tie(0)
#define close_cout cout.tie(0)
#define ct(a) cout<<a<<'\n'
#define sf1(a) scanf("%d",&a)
#define sf2(a,b) scanf("%d%d",&a,&b)
#define sf3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define gcd(a,b) __gcd(a,b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define sz size()
#define bg begin()
#define ed end()
#define cl clear()
#define fi first
#define se second
#define Repeat int T;cin>>T;while(T--)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> Pa;
typedef vector<int> Ve;
const double PI = acos(1.0);
const double eps = 1e-8;
int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 5;
const int M = 100 + 5;
struct edge{
int a, b, v;
}e[N];
int n, k;
int fa[N];
int ma[N];
void init()
{
repu(i,0,N-1)
fa[i] = i;
}
int Find(int x)
{
if(x != fa[x])
fa[x] = Find(fa[x]);
return fa[x];
}
void Merge(int x,int y)
{
int fx = Find(x);
int fy = Find(y);
if(fx != fy)
fa[fy] = fx;
}
bool cmp(edge a, edge b)
{
return a.v > b.v;
}
int main()
{
Repeat
{
mst(fa,0);
mst(ma,0);
init();
sf2(n,k);
repu(i,0,n-2)
sf3(e[i].a, e[i].b, e[i].v);
int t;
repu(i,1,k)
sf1(t), ma[t] = 1;
sort(e, e + n - 1, cmp);
ll sum = 0;
repu(i,0,n-2)
{
if(ma[Find(e[i].a)] && ma[Find(e[i].b)])
sum += e[i].v;
else if(ma[Find(e[i].a)])
Merge(e[i].a, e[i].b);
else
Merge(e[i].b, e[i].a);
}
ct(sum);
}
return 0;
}