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

POJ1679 The Unique MST

編輯:C++入門知識

題意:判斷最小生成樹是否唯一
思路:第一次用kruskal求出最小生成樹,記為ans,然後依次去除已經選進來的邊,進行kruskal,如果ans==kruskal()的話,則輸出不唯一。
注意:1.第一次求kruskal時記得要先判斷是否能生成最小生成樹(但是我沒判斷就A了。。理論上來說是要判斷的。。)
2.注意存放變的數組開大一點。我用G++交了幾次一直WA,原代碼改成C++交就RE,然後數組改了下大小就A了。被G++坑死了。
[cpp] 
#include <iostream> 
#include <cstdio> 
#include <algorithm> 
#include <string> 
#include <cmath> 
#include <cstring> 
#include <queue> 
#include <set> 
#include <vector> 
#include <stack> 
#include <map> 
#include <iomanip> 
#define PI acos(-1.0) 
#define Max 20005 
#define inf 1<<28 
using namespace std; 
 
struct kdq 

    int s,e,l; 
} road[Max]; 
int f[Max]; 
bool visit[Max]; 
bool visit1[Max]; 
int n,m; 
 
bool cmp(kdq x,kdq y ) 

    return x.l<y.l; 

 
int find(int x) 

    return f[x]==x?x:f[x]=find(f[x]); 

 
void Union(int x,int y) 

    x=find(x); 
    y=find(y); 
    if(x==y)return ; 
    if(y>x) 
        f[y]=x; 
    else 
        f[x]=y; 

 
int kruskal(int d)//d是用來刪除邊的 

    int num=0; 
    int num1=0; 
    for(int i=0; i<m; i++) 
    { 
        if(i!=d) 
        { 
            int x=find(road[i].s); 
            int y=find(road[i].e); 
            if(y!=x) 
            { 
                num1++; 
                Union(x,y); 
                num+=road[i].l; 
                visit[i]=1;//記錄第一次取來的邊的標號 
            } 
        } 
    } 
    if(num1==n-1)//判斷能生成最小生成樹 
    return num; 
    else 
    return -1; 

 
int main() 

    int i,j,k,l,T; 
    cin>>T; 
    while(T--) 
    { 
        memset(visit,0,sizeof(visit)); 
        cin>>n>>m; 
        for(i=0; i<=n; i++) 
            f[i]=i; 
        for(i=0; i<m; i++) 
            scanf("%d%d%d",&road[i].s,&road[i].e,&road[i].l); 
        sort(road,road+m,cmp); 
        int ans=kruskal(-1); 
        for(i=0; i<m; i++) 
            visit1[i]=visit[i];//將第一標記的序號存入visit1[],因為visit[]在接下來的kruskal中還會改變 
        if(ans==-1)//這個判斷不需要也可以過。。難道是數據水了? 
        { 
            cout<<0<<endl; 
            continue; 
        } 
        bool flag=0; 
        for(i=0; i<m; i++) 
        { 
            if(visit1[i])//如果是第一次取到的邊 
            { 
                for(j=0; j<=n; j++) 
                    f[j]=j; 
                if(kruskal(i)==ans)//如果刪除了這條邊後,最小生成樹的值相等,則說明不唯一 
                { 
                    flag=1; 
                    break; 
                } 
            } 
        } 
        if(flag) 
            cout<<"Not Unique!"<<endl; 
        else 
            cout<<ans<<endl; 
    } 
    return 0; 


作者:kdqzzxxcc

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