程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> poj 3522 Slim Span (Kruskal+枚舉)

poj 3522 Slim Span (Kruskal+枚舉)

編輯:C++入門知識

題目大意:  在一個無向聯通圖中                       求一棵最大邊與最小邊差值最小的生成樹   解題思路:  最大邊與最小邊差值最小的生成樹                       換言之使得最小邊與最大邊的長度最接近                         任取一條邊為生成樹最小的邊,唯一存在一條最大邊最接近最小的邊                       對所有的邊從小到大排序                       差值最小的最大邊一定在最小邊後面                       並且是構成這個生成樹的最後一條邊!                       枚舉最小邊到第m-n+2小邊組成的生成樹,找出差值最小的   易錯點:      最小邊和最大邊可能是同一條邊   代碼:     [cpp]  #include <stdio.h>    #include <string.h>    #include <stdlib.h>    #define MAX 101    #define MAX_2 9000    #define INF 0x3f3f3f3f    typedef struct snode{       int x;       int y;       int s;   }span;   int father[MAX];      int comp(const void *a,const void *b)   {       span *pa=(span *)a;       span *pb=(span *)b;       return pa->s-pb->s;   }      void Empty(int n)   {       int i;       for(i=1;i<=n;i++)           father[i]=i;   }      int Find(int x)   {       int s,j;       s=x;       while(x!=father[x]) x=father[x];       while(s!=x)       {           j=father[s];           father[s]=x;           s=j;       }       return x;   }      void Union(int R1,int R2)   {       int r1,r2;       r1=Find(R1);       r2=Find(R2);       if(r1!=r2) father[r1]=r2;   }      int main ()   {       int n,m,i,j,min,start,end,num,a;       while(scanf("%d%d",&n,&m)!=EOF)       {           span spantree[MAX_2];           if(m==0&&n==0)               break;           for(i=0;i<m;i++)           {               scanf("%d%d%d",&spantree[i].x,&spantree[i].y,&spantree[i].s);           }           qsort(spantree,m,sizeof(spantree[0]),comp);  //把邊從小到大排序            for(i=0,end=0,start=0,min=INF;i<m-n+2;i++)   //最多m-n+2個生成樹            {               Empty(n);               for(j=i,num=0;j<m;j++)               {                   if(Find(spantree[j].x)!=Find(spantree[j].y))                   {                       Union(spantree[j].x,spantree[j].y);                       num++;            //某個生成樹的第num條邊                        if(num==1)        //第一條最小,num-1條最大                            start=spantree[j].s;                       if(num==n-1)      //易錯點**:是if不是else if,因為可能只有一條邊                            end=spantree[j].s;                   }                   if(num==n-1)                   {                       a=end-start;                       if(a<min)                       {                           min=a;    //找到最小的差值                        }                       break;                   }               }           }           if(min!=INF)  printf("%d\n",min);           else   printf("-1\n");       }       return 0;   }     #include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX 101 #define MAX_2 9000 #define INF 0x3f3f3f3f typedef struct snode{     int x;     int y;     int s; }span; int father[MAX];   int comp(const void *a,const void *b) {     span *pa=(span *)a;     span *pb=(span *)b;     return pa->s-pb->s; }   void Empty(int n) {     int i;     for(i=1;i<=n;i++)         father[i]=i; }   int Find(int x) {     int s,j;     s=x;     while(x!=father[x]) x=father[x];     while(s!=x)     {         j=father[s];         father[s]=x;         s=j;     }     return x; }   void Union(int R1,int R2) {     int r1,r2;     r1=Find(R1);     r2=Find(R2);     if(r1!=r2) father[r1]=r2; }   int main () {     int n,m,i,j,min,start,end,num,a;     while(scanf("%d%d",&n,&m)!=EOF)     {         span spantree[MAX_2];         if(m==0&&n==0)             break;         for(i=0;i<m;i++)         {             scanf("%d%d%d",&spantree[i].x,&spantree[i].y,&spantree[i].s);         }         qsort(spantree,m,sizeof(spantree[0]),comp);  //把邊從小到大排序         for(i=0,end=0,start=0,min=INF;i<m-n+2;i++)   //最多m-n+2個生成樹         {             Empty(n);             for(j=i,num=0;j<m;j++)             {                 if(Find(spantree[j].x)!=Find(spantree[j].y))                 {                     Union(spantree[j].x,spantree[j].y);                     num++;            //某個生成樹的第num條邊                     if(num==1)        //第一條最小,num-1條最大                         start=spantree[j].s;                     if(num==n-1)      //易錯點**:是if不是else if,因為可能只有一條邊                         end=spantree[j].s;                 }                 if(num==n-1)                 {                     a=end-start;                     if(a<min)                     {                         min=a;    //找到最小的差值                     }                     break;                 }             }         }         if(min!=INF)  printf("%d\n",min);         else   printf("-1\n");     }     return 0; }  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved