题目链接:
https://vjudge.net/problem/POJ-2377
题目大意:
给一个图,求最大生成树权值,如果不连通输出-1
思路:
kruskal算法变形,sort按边从大到小排序,就可以了,或者用一个maxn-w[u][v]作为<u, v>边的权值,直接用原来的kruskal算法求出权值,然后用maxn*(n-1)-sum就为最大生成树权值
1 #include<iostream> 2 #include<vector> 3 #include<queue> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdio> 7 #include<set> 8 #include<map> 9 #include<cmath> 10 using namespace std; 11 typedef pair<int, int> Pair; 12 typedef long long ll; 13 const int INF = 0x3f3f3f3f; 14 int T, n, m; 15 const int maxn = 2e4 + 10; 16 struct edge 17 { 18 int v, u, w; 19 bool operator < (const edge a)const 20 { 21 return w > a.w; 22 } 23 }; 24 edge e[maxn]; 25 int pa[maxn]; 26 int Find(int x) 27 { 28 return x == pa[x] ? x : pa[x] = Find(pa[x]);//路径压缩 29 } 30 void kruskal() 31 { 32 for(int i = 1; i <= n; i++)pa[i] = i; 33 sort(e, e + m); 34 ll ans = 0; 35 for(int i = 0; i < m; i++) 36 { 37 ll v = e[i].v, u = e[i].u, w = e[i].w; 38 ll x = Find(v), y = Find(u); 39 if(x != y) 40 { 41 pa[x] = y; 42 ans += w; 43 } 44 } 45 int tot = 0; 46 for(int i = 1; i <= n; i++)//判断是否联通,是否只有一个父节点是自己的点 47 { 48 if(pa[i] == i)tot++; 49 } 50 if(tot > 1)cout<<"-1"<<endl; 51 else cout<<ans<<endl; 52 } 53 int main() 54 { 55 cin >> n >> m; 56 for(int i = 0; i < m; i++)cin >> e[i].v >> e[i].u >> e[i].w; 57 kruskal(); 58 }
1 #include<iostream> 2 #include<vector> 3 #include<queue> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdio> 7 #include<set> 8 #include<map> 9 #include<cmath> 10 using namespace std; 11 typedef pair<int, int> Pair; 12 typedef long long ll; 13 const int INF = 0x3f3f3f3f; 14 int T, n, m; 15 const int maxn = 2e4 + 10; 16 struct edge 17 { 18 int v, u, w; 19 bool operator < (const edge a)const 20 { 21 return w < a.w; 22 } 23 }; 24 edge e[maxn]; 25 int pa[maxn]; 26 int Find(int x) 27 { 28 return x == pa[x] ? x : pa[x] = Find(pa[x]);//路径压缩 29 } 30 void kruskal() 31 { 32 for(int i = 1; i <= n; i++)pa[i] = i; 33 sort(e, e + m); 34 ll ans = 0; 35 for(int i = 0; i < m; i++) 36 { 37 ll v = e[i].v, u = e[i].u, w = e[i].w; 38 ll x = Find(v), y = Find(u); 39 if(x != y) 40 { 41 pa[x] = y; 42 ans += w; 43 } 44 } 45 int tot = 0; 46 for(int i = 1; i <= n; i++)//判断是否联通,是否只有一个父节点是自己的点 47 { 48 if(pa[i] == i)tot++; 49 } 50 ans = 100000LL * ((ll)n - 1) - ans; 51 if(tot > 1)cout<<"-1"<<endl; 52 else cout<<ans<<endl; 53 } 54 int main() 55 { 56 cin >> n >> m; 57 for(int i = 0; i < m; i++) 58 { 59 cin >> e[i].v >> e[i].u >> e[i].w; 60 e[i].w = 100000 - e[i].w; 61 } 62 kruskal(); 63 }