zoukankan      html  css  js  c++  java
  • Networking

    poj1287:http://poj.org/problem?id=1287

    题意:平面上有许多点,又有许多边。每条边有一定的长度,且只会连接两个不同的点。现需要从这些边中选择某些边,使得尽可能多的点直接或间接相连。同时,又要选取的边的总长度最小。

    题解:本题就是去除重边,然后kruska运用。去重时候,我采用一个二维数组选取最小的边放进数组,然后遍历数组,如果有边则struct存入要处理的边。但是,看了别人的看法;程中可无视重边,因为排序之后,每次总是把最小的边加入,而且没两个点只能加一次,所以可以无视。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 using namespace std;
     6 const int MAXN=1000;
     7 const int MAXM=10000;
     8 int pa[MAXN],cnt;
     9 int g[100][100]; //记录最短边 
    10 struct Node{
    11     int u;
    12     int v;
    13     int w;
    14     bool operator<(const Node &a)const{
    15         return w<a.w;
    16     }
    17 }edge[MAXM];
    18 int n,m;
    19 void UFset(){//初始化 
    20     for(int i=1;i<=n;i++)
    21      pa[i]=-1;
    22 }
    23 int Find(int x){
    24     int s;
    25     for(s=x;pa[s]>=0;s=pa[s]);
    26     while(s!=x){
    27         int temp=pa[x];
    28         pa[x]=s;
    29         x=temp;
    30     }
    31     return s;
    32 }
    33 void Union(int R1,int R2){
    34      int r1=Find(R1);
    35      int r2=Find(R2);
    36      int temp=pa[r1]+pa[r2];
    37      if(pa[r1]>pa[r2]){
    38          pa[r1]=r2;
    39          pa[r2]=temp;
    40      }
    41      else{
    42          pa[r2]=r1;
    43          pa[r1]=temp;
    44      }
    45     
    46 }
    47 void kruskal(){
    48     int sum=0;
    49     int u,v;
    50     int num=0;
    51     UFset();
    52     for(int i=1;i<cnt;i++){
    53         u=edge[i].u;v=edge[i].v;
    54         if(Find(u)!=Find(v)){
    55             sum+=edge[i].w;
    56             Union(u,v);
    57             num++;
    58         }
    59     if(num>=n-1)break;    
    60         
    61     }
    62     printf("%d
    ",sum);
    63     
    64 }
    65 int main(){
    66     int a,b,w;
    67     while(~scanf("%d",&n)&&n){
    68         scanf("%d",&m);
    69         cnt=1;
    70          for(int i=1;i<=n;i++)
    71            for(int j=1;j<=n;j++)
    72             g[i][j]=100000;
    73         for(int i=1;i<=m;i++){
    74           scanf("%d%d%d",&a,&b,&w);
    75           if(g[a][b]>w){//去重 
    76               g[a][b]=g[b][a]=w;
    77           
    78           }
    79         }
    80         for(int i=1;i<=n;i++)
    81           for(int j=1;j<=n;j++){
    82               if(g[i][j]!=100000){//转化边 
    83                       edge[cnt].u=i;
    84                      edge[cnt].v=j;
    85                     edge[cnt++].w=g[i][j];
    86                     g[i][j]=g[j][i]=100000;
    87               }
    88           }
    89         
    90          sort(edge+1,edge+cnt);//排序 
    91          kruskal();
    92     }
    93 }
    View Code
  • 相关阅读:
    MySQL (下篇)
    【JUC剖析】专栏总集篇
    CF1391D(思维)
    CF1393E2(字符串)
    洛谷P5405 [CTS2019]氪金手游(期望,容斥)
    P5293 [HNOI2019]白兔之舞(单位根反演)
    洛谷P5400 [CTS2019]随机立方体(计数)
    洛谷P5401 [CTS2019]珍珠(生成函数)
    支配树学习笔记
    UOJ455 雪灾与外卖(模拟费用流)
  • 原文地址:https://www.cnblogs.com/chujian123/p/3371979.html
Copyright © 2011-2022 走看看