POJ3436 Command Network [最小树形图]

POJ3436 Command Network

最小树形图裸题


傻逼poj回我青春

wa wa wa 的原因竟然是需要%.2f而不是.2lf

我还有英语作业音乐作业写不完了啊啊啊啊啊啊啊啊啊

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#define fir first
#define sec second
using  namespace std;
const int N = 1005, M = 1e6+5, inf = 1e9+7;

int n, m, x[N], y[N];
struct edge {
    int u, v;
    double w;
} e[M];
inline double dis(int u, int v) {
    return sqrt((x[u]-x[v])*(x[u]-x[v]) + (y[u]-y[v])*(y[u]-y[v]));
}
pair<double, int> fa[N];
int vis[N], id[N];
double zhu_liu(int root = 1) {
    double ans = 0;
    while(true) {
        for(int i=1; i<=n; i++) fa[i] = make_pair(inf, 0);
        for(int i=1; i<=m; i++) {
            int u = e[i].u, v = e[i].v;
            fa[v] = min(fa[v], make_pair(e[i].w, u));           
        }
        for(int i=1; i<=n; i++) if(i != root && !fa[i].sec) {
            return -1;
        }

        fa[root] = make_pair(0, 0);
        memset(vis, 0, sizeof(vis));
        memset(id, 0, sizeof(id));
        int num = 0;
        for(int i=1; i<=n; i++) if(i != root) {
            ans += fa[i].fir;
            int u = i;
            
            while(u != root && !vis[u]) vis[u] = i, u = fa[u].sec;
            if(u != root && vis[u] == i) {
                num++;
                while(id[u] != num) id[u] = num, u = fa[u].sec;
            }
        }
        if(!num) break;
        for(int i=1; i<=n; i++) if(!id[i]) id[i] = ++num;
        int cnt = 0;
        for(int i=1; i<=m; i++) {
            int u = e[i].u, v = e[i].v;
            double tmp = fa[v].fir;
            u = id[u]; 
            v = id[v];
            if(u == v) continue;
            e[++cnt] = (edge) {u, v, e[i].w - tmp};
        }
        n = num;
        m = cnt;
        root = id[root];
    }
    return ans;
}

int main() {
    //ios::sync_with_stdio(false); cin.tie(); cout.tie();
    while(cin >> n >> m) {
        for(int i=1; i<=n; i++) scanf("%d %d", &x[i], &y[i]);
        int cnt = 0;
        for(int i=1; i<=m; i++) {
            int u, v;
            scanf("%d %d", &u, &v);
            if(u == v) continue;
            e[++cnt] = (edge) {u, v, dis(u, v)};
        }
        m = cnt;
        double ans = zhu_liu();
        if(ans == -1) puts("poor snoopy");
        else printf("%.2f\n", ans);
    }
}
posted @ 2018-10-28 19:17  Candy?  阅读(...)  评论(... 编辑 收藏