NOIP 边权差值最小的生成树(小数据)

来源:互联网 发布:php编写的网站 编辑:程序博客网 时间:2024/05/18 22:08

NOIP 边权差值最小的生成树(小数据)
2017年7月15日
Kruskal算法


因为根据Kruskal算法的原理,最小生成树的最短边确定后,最长边也相应确定,他们的差值就确定(参见《算法导论》)。所以可以枚举最短边求出生成树。
仅限小数据。


#include<iostream>#include<cstdio>#include<string>#include<algorithm>#include<cstring>using namespace std;int N, M;struct Edges{    int x, y, v;}V[4000];int ans = 0;int MinDif = 52013140;//int FatherVertex[500];bool cmp(Edges a, Edges b){return a.v < b.v;}inline void UnionVertex(int a, int b){    FatherVertex[FatherVertex[a]] = FatherVertex[b];}inline void ResetFatherVertex(){    for(int i = 1; i <= N; i++) FatherVertex[i] = i;}inline int GetFatherVertex(int a){    if(FatherVertex[a] == a)    return a;    FatherVertex[a] = GetFatherVertex(FatherVertex[a]);    return FatherVertex[a];}void Putin(){    cin >> N >> M;    memset(FatherVertex, -1, sizeof(FatherVertex));    int a, b, c;    for(int i = 1; i <= M; i++){        cin >> a >> b >> c;        V[++ans].x = a;        V[ans].y = b;   V[ans].v = c;    }    for(int i = 1; i <= N; i++)        FatherVertex[i] = i;    sort(V + 1, V + 1 + M, cmp);}void Kruskal(int T){    ResetFatherVertex();    int upEdge = -1, downEdge = 100000;    int sum = 0;    for(int i = T; i <= M; i++){        if(GetFatherVertex(V[i].x) != GetFatherVertex(V[i].y)){            UnionVertex(V[i].x, V[i].y);            upEdge = max(upEdge, V[i].v);            downEdge = min(downEdge, V[i].v);            sum++;        }    }    if(sum == N - 1)        MinDif = min(abs(upEdge - downEdge), MinDif);}int main(){    Putin();    for(int i = 1; i <= M - N + 1; i++)     Kruskal(i);    if(MinDif > 42012140){        cout << -1 << endl;        return 0;    }    cout << MinDif << endl;    return 0;}
原创粉丝点击