您的位置:首页 > 其它

[POJ 3164][最小树形图]

2016-02-18 20:36 447 查看
朱刘算法

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define maxn 1005
using namespace std;

struct Edge{
	int u, v;
	double w;
}edge[maxn * maxn];

int pre[maxn], id[maxn], vis[maxn], n, m;

double in[maxn];

const double inf = 2e9;
const double eps = 1e-8;

//------------------------------------------------//
struct Point{
	int x, y;
}b[maxn];

double Sqr(double x){
	return x * x;
}
double dist(int x, int y){
	return sqrt(Sqr(b[x].x - b[y].x) + Sqr(b[x].y - b[y].y));
}
//------------------------------------------------//
double Directed_MST(int root, int V, int E){
	double ret = 0;
	while(true){
		for(int i = 1; i <= V; i++)
			in[i] = inf;
		for(int i = 1; i <= E; i++){
			int u = edge[i].u;
			int v = edge[i].v;
			if(u != v && in[v] > edge[i].w){
				in[v] = edge[i].w;
				pre[v] = u;
			}
		}
		
		in[root] = 0;
		
		for(int i = 1; i <= V; i++){
			if(i == root)continue;
		    if(in[i] - inf > -eps)
		        return -1;
		}

		int cnt = 0;
		
		memset(vis, 0, sizeof vis);
		memset(id, 0, sizeof id);
		
		
		
		for(int i = 1; i <= V; i++){
			ret += in[i];
			int v = i;
			while(v != root && id[v] == 0 && vis[v] != i){
				vis[v] = i;
				v = pre[v];
			}
			if(v != root && id[v] == 0){
				id[v] = ++ cnt;
				for(int u = pre[v]; u != v; u = pre[u])
				    id[u] = cnt;
			}
		}
		
		if(cnt == 0)return ret;

		for(int i = 1; i <= V; i++)
		    if(id[i] ==0)
				id[i] = ++ cnt;
				
		for(int i = 1; i <= E; i ++){
			int u = edge[i].u;
			int v = edge[i].v;
			edge[i].u = id[u];
			edge[i].v = id[v];
			if(id[u] != id[v])
				edge[i].w -= in[v];
		}
		
		V = cnt;
		root = id[root];
	}
}

int main(){
	while(scanf("%d%d", &n, &m) == 2){

		for(int i = 1; i <= n; i++)
		    scanf("%d%d", &b[i].x, &b[i].y);
		    
		for(int i = 1; i <= m; i++){
			scanf("%d%d", &edge[i].u, &edge[i].v);
			edge[i].w = dist(edge[i].u, edge[i].v);
		}
		
		double ans = Directed_MST(1, n, m);
		
		if(ans < 0)
		    printf("poor snoopy\n");
		else
			printf("%.2lf\n", ans);
	}

    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: