传送门
题意
分析
关于我去别人oj刷题顺便加强了一波数据这件事
分析一下,傲娇点只能链接一条边,说明他只能和一个连通块构造起来联系
首先我们把没有涉及到傲娇点的所有边构成最小生成树,然后如果构成了一个连通块,我们可以把每一个傲娇点插到连通块上,如果构成了多个连通块,那么必然无法构造出最小生成树
最后需要注意的是,需要特判 n = = 2 n == 2 n==2的情况,这个情况数据应该是没有给出来的,可以测一下
2 1 2
1 2
1 2 3
这组数据,应该是可以构造出来的
代码
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
#define _CRT_SECURE_NO_WARNINGS
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 10,M = 1e5 + 10;
const ll mod = 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
int gcd(int a, int b) {return (b > 0) ? gcd(b, a % b) : a;}
bool st[N],num[N];
int q[N];
int n,m,p;
struct edge{
int x,y,z;
}e[M];
bool cmp(edge a,edge b){
return a.z < b.z;
}
int find(int x){
if(x != q[x]) q[x] = find(q[x]);
return q[x];
}
int Kruskal(){
sort(e,e + m,cmp);
for(int i = 1;i <= n;i++) q[i] = i;
int ans = 0;
for(int i = 0;i < m;i++){
if(st[e[i].x] || st[e[i].y]) continue;
int a = find(e[i].x),b = find(e[i].y);
if(a != b){
ans += e[i].z;
q[a] = b;
}
}
return ans;
}
int main() {
scanf("%d%d%d",&n,&m,&p);
int l = p;
for(int i = 1;i <= p;i++){
int x;
scanf("%d",&x);
st[x] = true;
}
for(int i = 0;i < m;i++) scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
if(n == 2){
sort(e,e + m,cmp);
int ans = -1;
for(int i = 0;i < m;i++) if(e[i].x != e[i].y) ans = e[i].z;
di(ans);
return 0;
}
int ans = Kruskal();
int res = 0;
p = -1;
for(int i = 1;i <= n;i++){
if(st[i]) continue;
if(i == find(i)) res++,p = i;
}
if(res != 1) {
puts("-1");
return 0;
}
for(int i = 0;i < m;i++){
int x = e[i].x,y = e[i].y,z = e[i].z;
int a = find(e[i].x),b = find(e[i].y);
if(st[x] && st[y]) continue;
if(st[x] + st[y] == 0) continue;
if(st[x]){
if(num[x]) continue;
ans += z;
q[a] = b;
num[x] = true;
}
else{
if(num[y]) continue;
ans += z;
q[a] = b;
num[y] = true;
}
}
res = 0;
for(int i = 1;i <= n;i++) if(i == find(i)) res++;
if(res != 1) ans = -1;
di(ans);
return 0;
}
/**
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████+
* ◥██◤ ◥██◤ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃ + + + +Code is far away from
* ┃ ┃ + bug with the animal protecting
* ┃ ┗━━━┓ 神兽保佑,代码无bug
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/