HDu 6187 Destroy Walls(最大生成ツリー)
11354 ワード
タイトル:
nとmは、2次元平面上にn個の点があることを示す、mは壁を塞いで、各点の2次元平面上の座標を与えて、第iは壁を塞いで(u,v)、壁に塞がれた場所は歩けない.各壁の取り外しには1つの代価があり、現在、少なくともどれだけの壁を取り外すかを聞いて、各点が他の点(図連通)に到達できるように、最小限の取り外しを前提に代価をできるだけ少なくし、最小限の取り外しと最小の代価を出力することができる.
データ範囲:n<=1 e 5、m<=2 e 5、壁に自環と重辺が存在しないことを保証する
解法:
code:
nとmは、2次元平面上にn個の点があることを示す、mは壁を塞いで、各点の2次元平面上の座標を与えて、第iは壁を塞いで(u,v)、壁に塞がれた場所は歩けない.各壁の取り外しには1つの代価があり、現在、少なくともどれだけの壁を取り外すかを聞いて、各点が他の点(図連通)に到達できるように、最小限の取り外しを前提に代価をできるだけ少なくし、最小限の取り外しと最小の代価を出力することができる.
データ範囲:n<=1 e 5、m<=2 e 5、壁に自環と重辺が存在しないことを保証する
解法:
( )
,
,
, ,
,
, .
, ,
, .
, , .
:
, kruskal ,
n-1, .
code:
#include
using namespace std;
const int maxm=1e6+5;
struct Node{
int a,b,c;
}e[maxm];
int pre[maxm];
int n,m;
int ffind(int x){
return pre[x]==x?x:pre[x]=ffind(pre[x]);
}
bool cmp(Node a,Node b){
return a.c>b.c;
}
signed main(){
ios::sync_with_stdio(0);
while(cin>>n>>m){
for(int i=1;i<=n;i++)pre[i]=i;
for(int i=1;i<=n;i++){
int x,y;cin>>x>>y;
}
int tot=0;
for(int i=1;i<=m;i++){
int a,b,c;cin>>a>>b>>c;
e[i]={a,b,c};
tot+=c;
}
sort(e+1,e+1+m,cmp);
int cnt=0;
int sum=0;
for(int i=1;i<=m;i++){
int x=ffind(e[i].a);
int y=ffind(e[i].b);
if(x!=y){
pre[x]=y;
sum+=e[i].c;
cnt++;
if(cnt==n-1)break;
}
}
cout<<m-cnt<<' '<<tot-sum<<endl;
}
return 0;
}