赞
踩

裸的最小生成树,比赛时就差一点就写出来了。
如果建边不优化那么就有N平方的复杂度了,显然不行。
想到了利用点权先贪心出一个最小的,但是想偏了,排序连成一条线了,固有思维,总是以为必须不停的换点。
结果只需找到最小的点和其他点建边即可。
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; const long long maxn = 0x3f3f3f3f ; struct node { long long q,z,w; }mp[500500]; long long a[200500]; long long ww[200500]; long long ans ; long long n,m; bool cmp(node A ,node B ) { return A.w < B.w; } int find2(int x) { if ( x != a[x] ) { a[x] = find2(a[x]); } return a[x]; } int u(int x,int y) { int fx = find2(x); int fy = find2(y); if ( fx != fy ) { a[fx] = fy; return 1; } return 0; } void ku() { int tmm = 0; ans = 0; for (int i = 1 ;i < m + n; i++ ) { if (u(mp[i].q,mp[i].z)) { tmm++; ans += mp[i].w; // cout<<mp[i].q<<" "<<mp[i].z<<" "<<mp[i].w<<"\n"; } if (tmm == n -1 ) break; } cout<<ans<<"\n"; } int main() { cin>>n; cin>>m; long long mi ,p1; for (int i = 1 ;i <= n ; i++ ) a[i] = i; for (int i = 1 ; i <= n ; i++ ) cin>>ww[i]; mi = ww[1]; p1 = 1; for (int i = 2 ; i <= n ; i++ ) { if ( ww[i] < mi ) { p1 = i; mi = ww[i]; } } for (int i = 1 ;i <= m ; i++ ) { long long b,c,d; cin>>b>>c>>d; mp[i].q = b; mp[i].z = c; mp[i].w = d; } int pit = 1; for (int i = 1 ;i <= n ; i++ ) { if ( i != p1 ) { mp[m+pit].q = p1; mp[m+pit].z = i; mp[m+pit].w = ww[i]+ww[p1]; pit++; } } sort(mp+1,mp+m+n,cmp); ku(); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。