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 }