I 修改 最小生成树

 

 思路:我们可以通过差分思想来解决;

   对于一个n个数的序列,我们再给他定义一个n+1的位置,将其值置为0;

   那么,我们的任务就是将前n位数字都置为0;(前n位数一开始是任意的)  

   假如给出这样一个操作:     l,r,w,那么就a【l】就可以跟a【r+1】相等

   可以理解位:                      l定点向r定点建边

   那么,我们的任务就是,将所有顶点都连接到同一棵树,即为:生成树

   那么最小值即为最小生成树

代码如下:

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std; 
 4 int f[100009];
 5 struct node{
 6     int x,y,w;
 7 }a[200009];
 8 bool cmp(node a,node b){
 9     return a.w<b.w;
10 }
11 int find(int x){
12     return f[x]==x?x:(f[x]=find(f[x]));
13 }
14 void merge(int x,int y){
15     int yy=find(y);
16     f[yy]=find(x);
17 }
18 int main(void){
19     int m,n;
20     cin>>n>>m;
21     int x,y,w;
22     for(int i=1;i<=m;i++){
23         cin>>x>>y>>w;
24         a[i].x=x;
25         a[i].y=y+1;
26         a[i].w=w;
27     }
28     for(int i=1;i<=n+1;i++){
29         f[i]=i;
30     }
31     sort(a+1,a+1+m,cmp);
32     int cnt=0;
33     long long ans=0;
34     for(int i=1;i<=m;i++){
35         if(cnt==n){
36             break;
37         }
38         if(find(a[i].x)!=find(a[i].y)){
39             ans+=a[i].w;
40             cnt++;
41             merge(a[i].x,a[i].y);
42         }
43     }
44     if(cnt==n){
45         cout<<ans<<endl;
46     }else{
47         cout<<"-1"<<endl;
48     }
49     return 0;
50 }

 

   

posted @ 2021-02-17 19:08  古比  阅读(81)  评论(0编辑  收藏  举报