zoukankan      html  css  js  c++  java
  • Connect them

    zoj3204:

    最小生成树,要求最小字典序的解。

    用kruscal算法,先排序,输出的时候也要排序。

      1 /*
      2 zoj3204 
      3 
      4 
      5 解题思路:
      6 赤裸裸的最小生成树。只是要求输出字典序最小的连接方案。
      7 所以在边的排序时要注意了,有可能存在边的权值是相同的边。
      8 所以在这种情况下,要按他们的顶点序列排序。直接把STL搬上了,很好很强大。 */ 
      9 #include<iostream>
     10 #include<cstdio>
     11 #include<iostream>
     12 #include <stdio.h>
     13 #include <stdlib.h>
     14 #include <cstdio>
     15 #include <cstring>
     16 #include<cmath>
     17 #include<algorithm>
     18 using namespace std;//这句写的时候千万别丢,不然许多函数无法使用 
     19 const int MAX=110; 
     20 struct Node{
     21     int from, to;
     22     int w;
     23     
     24 }edge[MAX*MAX];//记录读取时边的端点和权值 
     25 
     26 Node ans[MAX*MAX];//记录构成最小生成树里面的边 (边端点) 
     27 int n;//点的个数 
     28 int fa[MAX];// 并查集的 
     29 int tol;//记录最小生成树边的个数 
     30 int cnt;//记录ans里的边的个数 
     31  void addedge(int u ,int v,int w){
     32      edge[tol].from=u;
     33      edge[tol].to=v;
     34      edge[tol].w=w;
     35      tol++;
     36      
     37  }//添加边额操作 
     38 void makeset(){
     39     for(int i=1;i<=n;i++){
     40     fa[i]=i;    
     41         
     42     }
     43     
     44 }//并查集的初始化 ,也可以直接初始化为-1 
     45 int Find(int x){
     46     while(x!=fa[x])
     47     x=fa[x];
     48     return x;
     49 }//并查集的查找操作 
     50 void uion(int x,int y){
     51     int a=Find(x);
     52     int b=Find(y);
     53     if(a!=b){
     54         ans[cnt].from=x;
     55         ans[cnt].to=y;
     56         cnt++;
     57         fa[a]=b;
     58         }
     59     
     60     }//并查集的合并操作 
     61 int cmp1(Node a,Node b){
     62     if(a.w!=b.w)return a.w<b.w;
     63     else {if(a.from==b.from)
     64         
     65     
     66           return a.to<b.to;
     67           else
     68           return a.from<b.from;
     69     }
     70 }//比较器首先按w从小到大排序,若w相等,则依次按照from,to进行排序 ,这是给边排序 
     71 int cmp2(Node a,Node b){
     72     
     73     if(a.from!=b.from)return a.from<b.from;
     74     else
     75     return a.to<b.to;
     76 }//这个比较器主要是给ans里面的边排序,使其按照要求输出 
     77 int main(){
     78     int t;
     79     scanf("%d",&t);
     80     while(t--){
     81         scanf("%d",&n);
     82         tol=0;
     83         cnt=0;//一定要在该处初始化tol,cnt否则会报超时的错误 
     84        makeset();
     85        int d;
     86         for(int i=1;i<=n;i++){
     87             
     88             for(int j=1;j<=n;j++){
     89                 scanf("%d",&d);
     90                 if(j<=i)continue;
     91                 if(d==0)continue;//这样读取会使避免重边的影响 
     92                 addedge(i,j,d);//前面的d会被后面的覆盖 
     93                 
     94             }
     95         }
     96         sort(edge,edge+tol,cmp1);//排序 
     97         for(int i=0;i<tol;i++)
     98              uion(edge[i].from,edge[i].to);
     99         
    100         sort(ans,ans+cnt,cmp2);
    101         if(cnt!=n-1){
    102         printf("-1
    ");
    103         continue;}//这一步很重要,是判断能不能形成最小生成树的 
    104         else{
    105             
    106         
    107         for(int i=0;i<cnt-1;i++){
    108             printf("%d %d ",ans[i].from,ans[i].to);//注意题目给出的输出格式 
    109             }
    110             printf("%d %d
    ",ans[cnt-1].from,ans[cnt-1].to);
    111             
    112     }
    113     }
    114     
    115 }
    View Code
  • 相关阅读:
    mssql sqlserver 验证整型函数分享
    SQL存储过程解密
    MSSQL sqlserver系统函数教程分享
    union的使用
    select子句
    软件测试用例设计方法
    软件测试模型与测试过程
    selenium定位元素方法
    kali渗透综合靶机(六)--FristiLeaks靶机
    kali渗透综合靶机(五)--zico2靶机
  • 原文地址:https://www.cnblogs.com/chujian123/p/3243328.html
Copyright © 2011-2022 走看看