程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ 1679 The Unique MST

POJ 1679 The Unique MST

編輯:C++入門知識

這是一個次小生成樹的題目,我們知道要求最小生成樹的方法,次小生成樹在最小生成樹的基礎上運算就可以了,這裡采用最簡單的方法就是去掉最小生成樹集合當中的每一條邊再做kruskal,每次kruskla的時間復雜度有mlogm+m,進行最小生成樹中邊集的枚舉復雜度為(n-1)*(m*logm+m),這題還是做到的,還有一種更好的方法,只要做一次kruskal就好了,實現起來有點復雜。

先貼本題的代碼:


[cpp] 
#include<iostream> 
#include<algorithm> 
#define maxn 105 
#define maxe 5050 
using namespace std; 
struct Edge 

       int a,b,w,flag; 
} e[maxe]; 
int n,m,c; 
int f[maxn],used[maxn]; 
void Set() 

     for(int i=1; i<=n; i++){ 
          f[i]=i; 
     } 

int Find(int x) 

     if( x!=f[x]) 
         f[x]=Find(f[x]); 
     return f[x]; 

bool cmp(Edge a,Edge b) 

      return a.w<b.w;  

int Kruskal() 

    int i,x,y,ret; 
    ret=0; c=0; 
    Set(); 
    for( i=0; i<m&&c<n-1; i++){ 
         x=Find(e[i].a); 
         y=Find(e[i].b); 
         if( x==y) continue; 
         f[x]=y; 
         ret+=e[i].w; 
         used[c++]=i;  
    } 
    return (c<n-1? 0:ret);          

int SecKruskal() 

    int i,x,y,ret,count; 
    ret=0; count=0; 
    Set(); 
    for( i=0; i<m&&count<n-1; i++){ 
         x=Find(e[i].a); 
         y=Find(e[i].b); 
         if( x==y|| e[i].flag) continue; 
         f[x]=f[y]; 
         ret+=e[i].w; 
         count++;  
    } 
    return ( count<n-1? 0:ret);          

     
int main() 

    int t,mst,smst,pt,i; 
    scanf("%d",&t); 
    while( t--){ 
           scanf("%d%d",&n,&m); 
           memset(e,0,sizeof(e));  
           memset(used,0,sizeof(used)); 
           memset(f,0,sizeof(f)); 
           for( i=0; i<m; i++) 
                scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].w);      
           sort(e,e+m,cmp);    //按邊值大小排序  
            
           mst=Kruskal();    //第一次kruskal求最小生成樹 mst  
            
           pt=0;  //最小生成樹不同至少要有一條邊不同。  
           for( i=0; i<c; i++){ 
                e[used[i]].flag=1; 
                smst=SecKruskal(); 
                e[used[i]].flag=0; 
                if( smst==mst&&smst!=0){   //如果最小樹不是唯一的。 
                    pt=1; 
                    break; 
                }   
           }     
           if( pt) 
               printf("Not Unique!\n"); 
           else 
               printf("%d\n",mst);     
    } 
    return 0;  


作者:aacm1992

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