最小生成树-prim

来源:互联网 发布:spss输入数据 编辑:程序博客网 时间:2024/05/21 14:44

生成树集合A,每次选择A外的key[v]最小的点加入A,key[v]为v与所有A中的点距离最小值。

#include <iostream>

#include <cstdio>

#include <algorithm>

#include <vector>

#include <queue>

#include <cmath>

#include <cstring>

using namespacestd;


const int maxn =105;

const double INF =1 << 25;


struct point{

    int x,y;

}p[maxn];

struct edge{

    int v;

    double w;

};

typedef pair<double,int> pr;


vector<edge> mp[maxn];

double key[maxn];//key[v] = min{edge(u to v),u属于已建成的最小生成树A}

bool vis[maxn];


void init(int c)

{

    

    for (int i =1; i <= c; i ++) {

        key[i] =INF;

        mp[i].clear();

    }

    memset(vis,false, sizeof(vis));

   }

void input(int c)

{

    for (int i =1; i <= c; i ++) {

        scanf("%d%d",&p[i].x,&p[i].y);

    }

    int t;

    for (int i =1; i <= c; i ++) {

        for (int j= i +1; j <= c; j ++) {

            t = (p[i].x -p[j].x) * (p[i].x -p[j].x) + (p[i].y -p[j].y) * (p[i].y -p[j].y);

            if (100 <= t && t <=1e6) {

                mp[i].push_back({j,sqrt(1.0 *t)});

                mp[j].push_back({i,sqrt(1.0 *t)});

            }

        }

    }


}

double f(int c,int s)

{

    double ans =0;

    int cnt =0;

    priority_queue<pr,vector<pr>,greater<pr> > pq;

    key[s] =0;

    pq.push({key[s],s});

    while (cnt < c) {

        pr u = pq.top();

        pq.pop();

        int th = u.second;

        vis[th] =true;

        ans += key[th];

        cnt ++;

        for (int i =0; i < mp[th].size(); i ++) {

            edge &e =mp[th][i];

                if (!vis[e.v] &&key[e.v] >  e.w) {

                    key[e.v] =  e.w;

                    pq.push({key[e.v],e.v});

                }

            }

        while (!pq.empty() &&vis[pq.top().second]) {

            pq.pop();

        }

    }

    if (cnt == c) {

        return ans;

    }

    else return ans = -1;

}

int main()

{

    int t;

    cin >> t;

    while (t --) {

        int c;

        cin >> c;

        init(c);

        input(c);

        double res =f(c,1);

        if (res == -1) {

            cout <<"oh!" << endl;

        }

        elseprintf("%.1lf\n",res *100);

    }

    return0;

}


0 0
原创粉丝点击