POJ - 3164-Command Network 最小树形图——朱刘算法

POJ - 3164 

题意:

一个有向图,存在从某个点为根的,可以到达所有点的一个最小生成树,则它就是最小树形图。

  题目就是求这个最小的树形图。

参考资料:https://blog.csdn.net/txl199106/article/details/62045479

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <list>
#include <cstdlib>
#include <iterator>
#include <cmath>
#include <iomanip>
#include <bitset>
#include <cctype>
using namespace std;
//#pragma comment(linker, "/STACK:102400000,102400000")  //c++
#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue

typedef long long ll;
typedef unsigned long long ull;

typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;

//priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
#define endl '\n'

#define OKC ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define FT(A,B,C) for(int A=B;A <= C;++A)  //用来压行
#define REP(i , j , k)  for(int i = j ; i <  k ; ++i)
//priority_queue<int ,vector<int>, greater<int> >que;

const ll mos = 0x7FFFFFFF;  //2147483647
const ll nmos = 0x80000000;  //-2147483648
const int inf = 0x3f3f3f3f;

template<typename T>
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x=f?-x:x;
}
// #define _DEBUG;         //*//
#ifdef _DEBUG
freopen("input", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
/*-----------------show time----------------*/


int n,m;

struct nn
{
    int x,y;
}a[110];

struct node
{
    int u,v;
    double dis;
}e[10009];
double get(int i,int j){
    return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x) + (a[i].y-a[j].y)*(a[i].y-a[j].y));
}

double in[110];
int id[110],vis[110];
int pre[110];
int flag = 1;
double zhuliu(int root){
    double ans = 0.0;
    while(true){
        for(int i=1; i<=n; i++){
            in[i] = 9999999999.99;
        }
        
        for(int i=1; i<=m; i++){
            node & b = e[i];
            if(b.u!=b.v && in[b.v] > e[i].dis){
                in[b.v] = e[i].dis;
                pre[b.v] = b.u;
            }
        }
        
        for(int i=1; i<=n; i++){
            if(i!=root&&in[i]>=9999999999.99){
                flag = 0;
                return -1;
            }
        }
        
        memset(id,-1,sizeof(id));
        memset(vis,-1,sizeof(vis));
        in[root] = 0; int num = 1;
        for(int i=1; i<=n; i++){
            ans += in[i];
//            debug(ans);
            int v = i;
            while(vis[v]!=i && v!=root&&id[v]==-1){
                vis[v] = i;
                v = pre[v];
            }
            if(v!=root&&id[v] ==-1){
                for(int u=pre[v] ; u!=v; u = pre[u]){
                    id[u] = num;
                }
                id[v]=num++;
            }
        }
        if(num==1)break;
        
        for(int i=1; i<=n; i++){
            if(id[i] == -1){
                id[i]=num++;
            }
        }
        
        for(int i=1; i<=m; i++){
            int v = e[i].v;
            
            e[i].u = id[e[i].u];
            e[i].v = id[e[i].v];
            if(e[i].u!=e[i].v)
                e[i].dis = e[i].dis - in[v];
        }
        n = num-1;
        root = id[root];
    }
    return ans;
}

int  main(){
    while(~scanf("%d%d", &n, &m)){
        for(int i=1; i<=n; i++){
            scanf("%d%d", &a[i].x, &a[i].y);
        }
        
        for(int i=1; i<=m; i++){
            scanf("%d%d", &e[i].u, &e[i].v);
            e[i].dis = get(e[i].u, e[i].v);
        }
        flag = 1;
        double tmp = zhuliu(1);
        if(flag==0)puts("poor snoopy");
        else printf("%.2f\n",tmp);
    }
    
    
    return 0;
}
POJ-3164

 

posted @ 2018-07-31 09:12  ckxkexing  阅读(128)  评论(0编辑  收藏  举报