1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| #include<bits/stdc++.h> #define fo(i,a,b) for(int i=a;i<=b;i++) using namespace std;
typedef long long LL; typedef pair<int,bool> pr;
const int maxn=1e5+5, maxm=150005;
struct EST{ int x,y,w; }; bool cmpE(const EST &a,const EST &b) {return a.w<b.w;}
int n,m,sqrtm; EST e[maxm]; unordered_map<int,bool> M[maxn];
int ga[maxn],size[maxn],nbrsize[maxn]; unordered_map<int,bool> nbr[maxn],bignbr[maxn]; bool issmall[maxn]; int get(int x) {return ga[x]==x ?x :ga[x]=get(ga[x]) ;}
int main() { scanf("%d %d",&n,&m); sqrtm=sqrt(m<<1); fo(i,1,m) { scanf("%d %d %d",&e[i].x,&e[i].y,&e[i].w); if (e[i].x==e[i].y) continue; M[e[i].x][e[i].y]=1; M[e[i].y][e[i].x]=1; } fo(i,1,n) issmall[i]=(M[i].size()<=sqrtm); fo(i,1,n) for(pr p:M[i]) if (issmall[p.first]) nbr[i][p.first]=1, nbrsize[i]++; else bignbr[i][p.first]=1; fo(i,1,n) ga[i]=i, size[i]=1; sort(e+1,e+1+m,cmpE); LL ans=0; fo(i,1,m) if (get(e[i].x)!=get(e[i].y)) { int x=get(e[i].x), y=get(e[i].y); if (nbr[x].size()>nbr[y].size()) swap(x,y); if (issmall[x]) nbr[y].erase(x), nbrsize[y]-=size[x]; else bignbr[y].erase(x); if (issmall[y]) nbr[x].erase(y), nbrsize[x]-=size[y]; else bignbr[x].erase(y); #define go p.first int comsize=0, xsize=nbrsize[x], ysize=nbrsize[y]; for(pr p:nbr[x]) if (nbr[y].count(go)) comsize+=size[go]; for(pr p:bignbr[x]) if (!bignbr[y].count(go)) xsize+=size[go]; for(pr p:bignbr[y]) if (!bignbr[x].count(go)) ysize+=size[go]; ans+=((LL)size[x]*(ysize-comsize)+(LL)size[y]*(xsize-comsize))*e[i].w; ga[x]=y; if (issmall[x]) { for(pr p:nbr[x]) nbr[go].erase(x), nbrsize[go]-=size[x]; for(pr p:bignbr[x]) nbr[go].erase(x), nbrsize[go]-=size[x]; } else { for(pr p:nbr[x]) bignbr[go].erase(x); for(pr p:bignbr[x]) bignbr[go].erase(x); } if (issmall[y] && nbr[y].size()>sqrtm) { for(pr p:nbr[y]) nbr[go].erase(y), nbrsize[go]-=size[y]; for(pr p:bignbr[y]) nbr[go].erase(y), nbrsize[go]-=size[y]; for(pr p:nbr[y]) bignbr[go][y]=1; for(pr p:bignbr[y]) bignbr[go][y]=1; for(pr p:nbr[x]) bignbr[go][y]=1; for(pr p:bignbr[x]) bignbr[go][y]=1; issmall[y]=0; } else { if (issmall[y]) { for(pr p:nbr[y]) nbrsize[go]+=size[x]; for(pr p:bignbr[y]) nbrsize[go]+=size[x]; for(pr p:nbr[x]) if (!nbr[go].count(y)) nbr[go][y]=1, nbrsize[go]+=size[x]+size[y]; for(pr p:bignbr[x]) if (!nbr[go].count(y)) nbr[go][y]=1, nbrsize[go]+=size[x]+size[y]; } else { for(pr p:nbr[x]) bignbr[go][y]=1; for(pr p:bignbr[x]) bignbr[go][y]=1; } } for(pr p:nbr[x]) if (!nbr[y].count(go)) nbr[y][go]=1, nbrsize[y]+=size[go]; nbr[x].clear(); for(pr p:bignbr[x]) bignbr[y][go]=1; bignbr[x].clear(); size[y]+=size[x]; } printf("%lld\n",ans); }
|