zoukankan      html  css  js  c++  java
  • 最大生成树

    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
  • 相关阅读:
    字符串String
    冒泡排序、二分查找法
    数组习题
    数组
    附加习题
    编写Java程序,应用for循环打印菱形、三角形
    JAVA的语法基础4
    3.20 每日一题题解
    3.19 每日一题题解
    3.18 每日一题题解
  • 原文地址:https://www.cnblogs.com/wolf940509/p/5751684.html
Copyright © 2011-2022 走看看