最大生成树

POJ2377

题意:求最大生成树

分析:把边权值变成负值,最后取绝对值,注意最后的判断,如果生成树的边的数目小于(顶点数-1)则表示不能构成生成树

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <string>
 5 #include <vector>
 6 #include <algorithm>
 7 #include <set>
 8 #include <map>
 9 #include <bitset>
10 #include <cmath>
11 #include <queue>
12 #include <stack>
13 using namespace std;
14 const int maxn=20020;
15 int  par[maxn],rankl[maxn];
16 
17 void init(int n)
18 {
19     for(int i=0;i<=n;i++)
20     {
21         par[i]=i;
22         rankl[i]=0;
23     }
24 }
25 int findl(int x)
26 {
27     if(par[x]==x)
28         return x;
29     else
30         return par[x]=findl(par[x]);
31 }
32 void unite(int x,int y)
33 {
34     x=findl(x);
35     y=findl(y);
36     if(x==y)  return;
37     if(rankl[x]<rankl[y]){
38         par[x]=y;
39     }else{
40         par[y]=x;
41         if(rankl[x]==rankl[y])   rankl[x]++;
42     }
43 }
44 bool same(int x,int y)
45 {
46     return findl(x)==findl(y);
47 }
48 int n,m;
49 struct edge{
50     int u,v,cost;
51 };
52 bool cmp(const edge e1,const edge e2){
53     return e1.cost<e2.cost;
54 }
55 edge es[maxn];
56 int ans;
57 int kruskal()
58 {
59     sort(es,es+m+1,cmp);
60     init(n);
61     int res=0;
62     for(int i=0;i<m;i++){
63         edge e=es[i];
64         if(!same(e.u,e.v)){
65             unite(e.u,e.v);
66             res+=e.cost;
67             ans++;
68         }
69     }
70     return res;
71 }
72 int main()
73 {
74     while(cin>>n>>m)
75     {
76         for(int i=0;i<m;i++)
77         {
78             int a,b,c;
79             scanf("%d%d%d",&a,&b,&c);
80             es[i].u=a,es[i].v=b,es[i].cost=-c;
81         }
82         ans=0;
83         int cnt=0-kruskal();
84     //    cout<<ans<<endl;
85         if(ans==n-1)
86         cout<<cnt<<endl;
87         else
88         cout<<"-1"<<endl;
89     }
90     return 0;
91 }
View Code

AOJ2224

题意:给定一个图,并给出每条边的一些信息,问要让这个图构成树,去掉的最小长度是多少

分析:因为求的是去掉的最小长度,所以剩下的必然是最大的,这就是一个最大生成树问题,注意一下输入问题,开始给定的是点的坐标,后面给定的是哪些点是联通的

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <string>
  5 #include <vector>
  6 #include <algorithm>
  7 #include <set>
  8 #include <map>
  9 #include <bitset>
 10 #include <cmath>
 11 #include <queue>
 12 #include <stack>
 13 using namespace std;
 14 const int maxn=10100;
 15 const int maxm=10000*10000/2;
 16 int par[maxn],rankl[maxn];
 17 
 18 //并查集
 19 void init(int n)
 20 {
 21     for(int i=0;i<=n;i++)
 22     {
 23         par[i]=i;
 24         rankl[i]=0;
 25     }
 26 }
 27 int findl(int x)
 28 {
 29     if(par[x]==x)
 30         return x;
 31     else
 32         return par[x]=findl(par[x]);
 33 }
 34 void unite(int x,int y)
 35 {
 36     x=findl(x);
 37     y=findl(y);
 38     if(x==y)  return;
 39     if(rankl[x]<rankl[y]){
 40         par[x]=y;
 41     }else
 42     {
 43         par[y]=x;
 44         if(rankl[x]==rankl[y])  rankl[x]++;
 45     }
 46 }
 47 bool same(int x,int y)
 48 {
 49     return findl(x)==findl(y);
 50 }
 51 struct edge{
 52     int u,v;
 53     double cost;
 54 };
 55 bool cmp(const edge e1,const edge e2)
 56 {
 57     return e1.cost<e2.cost;
 58 }
 59 edge es[maxm];
 60 int n,m;
 61 double kruskal()
 62 {
 63     sort(es+1,es+m+1,cmp);
 64     init(n);
 65     double res=0;
 66     for(int i=1;i<=m;i++){
 67         edge e=es[i];
 68         if(!same(e.u,e.v)){
 69             unite(e.u,e.v);
 70             res+=e.cost;
 71         }
 72     }
 73     return res;
 74 }
 75 double  a[maxn],b[maxn];
 76 struct app
 77 {
 78     int x,y;
 79 };
 80 app s[maxm];
 81 double distance(double x1,double y1,double  x2,double  y2)
 82 {
 83     double t1=(x1-x2)*(x1-x2);
 84     double t2=(y1-y2)*(y1-y2);
 85     return sqrt(t1+t2);
 86 }
 87 int main()
 88 {
 89     while(cin>>n>>m)
 90     {
 91         memset(a,0,sizeof(a));
 92         memset(b,9,sizeof(b));
 93         for(int i=1;i<=n;i++)     //输入点的坐标
 94         {
 95             scanf("%lf%lf",&a[i],&b[i]);
 96         }
 97         double hh=0.0;
 98         for(int i=1;i<=m;i++)   //输入有边的点
 99         {
100             scanf("%d%d",&s[i].x,&s[i].y);
101             int x=s[i].x,y=s[i].y;
102             es[i].u=x,es[i].v=y;
103             es[i].cost=-distance(a[x],b[x],a[y],b[y]);
104              hh+=-es[i].cost;
105         }
106         double tt=0-kruskal();
107         printf("%.3lf
",hh-tt);
108     }
109     return 0;
110 }
View Code
原文地址:https://www.cnblogs.com/wolf940509/p/5751684.html