• EOJ-2614 组网计划


    http://acm.cs.ecnu.edu.cn/problem.php?problemid=2614

    题意:求其最小生成树,且判断最小生成树是否唯一。

    prim法,判断唯一的方法:进行两次prim,第一次,每次加最小边时当出现多个最小边时,总是添加结点编号较小的那个,而第二次总是添加较大那个 (即若总是无多个最小边选择,最小生成树必是唯一的),若生成树是完全相同的则唯一,方法是:两次分别记录加边的情况,若加边情况相同则其唯一,否则有多个解。

     1 #include<map>
     2 #include<set>
     3 #include<list>
     4 #include<cmath>
     5 #include<ctime>
     6 #include<queue>
     7 #include<stack>
     8 #include<cctype>
     9 #include<cstdio>
    10 #include<string>
    11 #include<cstdlib>
    12 #include<cstring>
    13 #include<iostream>
    14 #include<algorithm>
    15 using namespace std;
    16 const int inf=0x3f3f3f3f;
    17 int mat[105][105];
    18 int n;
    19 int a[105],b[105];        //记录加边顺序
    20 void init(){
    21     for(int i=1;i<=n;i++)
    22         for(int j=1;j<=n;j++)
    23         mat[i][j]=inf;
    24 }
    25 int prim(bool flag){
    26     int lowcost[105],s[105];
    27     int ans=0;
    28     for(int i=1;i<=n;i++){
    29         lowcost[i]=mat[1][i];
    30         s[i]=0;
    31     }
    32     s[1]=1;
    33     for(int i=1;i<=n;i++){
    34         int min=inf,k;
    35         if(flag){
    36             for(int j=1;j<=n;j++)
    37                 if(!s[j] && lowcost[j]<=min){            //"<="判断条件使得可有多个选择,并总是更新编号较大的
    38                     min=lowcost[j];
    39                     k=j;
    40                     a[i]=k;                                //记录加边顺序
    41                 }
    42         }else{
    43             for(int j=n;j>=1;j--)                        //总是更新编号较小的
    44                 if(!s[j] && lowcost[j]<=min){
    45                     min=lowcost[j];
    46                     k=j;
    47                     b[i]=k;                                //记录加边顺序
    48                 }
    49         }
    50         if(min==inf) break;
    51         ans+=min;
    52         s[k]=1;
    53         for(int j=1;j<=n;j++)
    54             if(!s[j] && mat[k][j]<lowcost[j])
    55                 lowcost[j]=mat[k][j];
    56     }
    57     return ans;
    58 }
    59 int main(){
    60     while(~scanf("%d",&n)){
    61         init();                            //初始化
    62         int x[105],y[105];
    63         for(int i=1;i<=n;i++)
    64             scanf("%d%d",x+i,y+i);
    65         for(int i=1;i<=n;i++)
    66             for(int j=i+1;j<=n;j++)
    67                 mat[i][j]=mat[j][i]=abs(x[i]-x[j])+abs(y[i]-y[j]);    //建图用的曼哈顿距离
    68         int reta=prim(1),retb=prim(0);        //进行两次prim,参数1代表总是取较大边,0代表总是取较小边
    69         printf("%d
    ",reta);
    70         bool f=0;
    71         for(int i=1;i<n;i++)
    72             if(a[i]!=b[i]){printf("Yes
    ");f=1;break;}            //若加边顺序不同一定有多种情况
    73         if(!f)printf("No
    ");
    74     }
    75     return 0;
    76 }
    View Code
  • 相关阅读:
    Fody is only supported on MSBuild 16 and above
    abp发送邮件AbpMailKit
    看一位老司机的博文,分享一下。
    nginx PC 移动配置
    微信开放平台登录
    flask 中 session的源码解析
    python mac环境搭建
    前端换mac可以参考搭一下简单的环境
    vue 导航钩子
    HTML5 History 模式
  • 原文地址:https://www.cnblogs.com/KimKyeYu/p/3149223.html
Copyright © 2020-2023  润新知