1. 程式人生 > 實用技巧 >hdu 6763 Total Eclipse 並查集+思維

hdu 6763 Total Eclipse 並查集+思維

http://acm.hdu.edu.cn/showproblem.php?pid=6763題目連結

題意

n 個城市 b條路 每個城市都有燈 每個燈都有亮度 每次從聯通的城市裡面選擇一些亮度一起-1;問要減多少次;

做法:

並查集+sort 先按照亮度排序,把所有點看成孤立的,ans+=當前節點亮度,由於會多加,後面開始減; 然後建圖,按照亮度從大到小倒著讀 ,每次遍歷與當前節點有連邊的且訪問過的節點 ,如果不在一個集合裡面ans-=當前節點亮度(母節點,由於之前算的時候多加了這個節點的亮度,本來可以一起)並加入到一個集合裡面去。重複操作。結束

程式碼

#include<bits/stdc++.h>
using
namespace std; int f[2000005]; struct st{ long long b,i; }s[100005]; int vis[2000005]; vector<int >g[100005]; int ff(int x){ if(x==f[x]){ return x; } else{ return f[x]=ff(f[x]); } } bool cmp(const st &x,const st &y){ return x.b>y.b; } int main(){ int
t; cin>>t; while(t--){ int n,m; cin>>n>>m; long long ans=0; for(int i=1;i<=n;i++){ f[i]=i; vis[i]=0; scanf("%d",&s[i].b); ans+=s[i].b; s[i].i=i; g[i].clear(); } sort(s
+1,s+1+n,cmp); for(int i=1;i<=m;i++){ int u,v; scanf("%d%d",&u,&v); g[u].push_back(v); g[v].push_back(u); } for(int i=1;i<=n;i++){ for(auto v:g[s[i].i]){ if(vis[v]){ int w=ff(v); if(w!=ff(s[i].i)){ f[w]=ff(s[i].i); ans-=s[i].b; } } } vis[s[i].i]=1; } cout<<ans<<endl; } }