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?  阅读(382)  评论(0编辑  收藏  举报