kruskal_poj 3522 Slim Span

題意爲求一棵生成樹,其最大邊權-最小邊權最小

先枚舉生成樹中的最小邊,再用kruscal求最小生成樹

http://poj.org/problem?id=3522

#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>

using namespace std;

#define PB push_back
#define MP make_pair
#define MAXVN 110
#define MAXEN 5500
#define INF 1000000000

#define REP(i,n) for(i=0;i<(n);++i)
#define FOR(i,l,h) for(i=(l);i<=(h);++i)
#define FORD(i,h,l) for(i=(h);i>=(l);--i)

typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<double> VD;
typedef long long LL;
typedef pair<int,int> PII;

typedef struct{
    int u, v, value;
}Edge;

Edge eg[MAXEN];
int p[MAXVN],rank[MAXVN];

void MAKE_SET(int x){
    p[x] = x;
    rank[x] = 0;
}

int FIND_SET(int x){
    if(x != p[x])
        p[x] = FIND_SET(p[x]);
    return p[x];
}

void LINK_SET(int x, int y){
    if(rank[x] > rank[y]) p[y] = x;
    else{
        p[x] = y;
        if(rank[x] == rank[y]) rank[y]+=1;
    }
}

void UNION_SET(int x, int y){
    LINK_SET(FIND_SET(x), FIND_SET(y));
}

int cmp(const void *a, const void *b){
    return (*(Edge *)a).value - (*(Edge *)b).value;
}
int function(int vn, int en){
    qsort(eg, en, sizeof(eg[0]), cmp);
    int minv, maxv,minall  = INF,count,flag = 0;
    for(int i = 0; i < en; i++){
        minv = eg[i].value;
        maxv = -INF;
        if(en - i < vn - 1) break;
        count = 0;
        for(int j = 0; j <= vn; j++) MAKE_SET(j);
        for(int j = i; j < en; j++){
            if(FIND_SET(eg[j].u) != FIND_SET(eg[j].v)){
                UNION_SET(eg[j].u, eg[j].v);
                count++;
                if(eg[j].value > maxv) maxv = eg[j].value;
                if(maxv - minv > minall) break;
            }
        }
        //printf("count:%d\n", count);
        if(count == vn - 1 && maxv-minv < minall) {
            minall = maxv- minv;
            flag = 1;
        }
    }
    if(!flag) minall = -1;
    return minall;
}

int main(){
	int vn, en;
	//freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
	while(scanf("%d%d", &vn, &en)&&(vn||en)){
        for(int i = 0; i < en; i++){
            scanf("%d%d%d", &eg[i].u, &eg[i].v, &eg[i].value);
        }
        int a = function(vn, en);
        printf("%d\n", a);
	}

	return 0;
}


 

發佈了100 篇原創文章 · 獲贊 8 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章