zoukankan      html  css  js  c++  java
  • POJ 1751

    此前做过思路类似的,很明显的Kruskal,将一个森林逐渐并成一颗树

    又是一个玄学问题,当时写读取顺手写了一个对于多组输入或是单组输入都适用的while写法,不过反而WA了,以后还是具体问题具体分析吧

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    using namespace std;
    
    const int maxn= 755;
    const double INF= 1e9;
    
    struct Edge
    {
    	int u, v;
    	double c;
    	Edge(int _u= 0, int _v= 0, double _c= 0) : u(_u), v(_v), c(_c) {}
    	bool operator < (const Edge &rhs) const
    	{
    		return c< rhs.c;
    	}
    }G[maxn*maxn];
    int x[maxn], y[maxn];
    int fa[maxn], rk[maxn];
    int pre[maxn];
    double co[maxn];
    vector<pair<int, int>> plan;
    
    int Find(int x)
    {
    	if (x== fa[x]){
    		return x;
    	}
    
    	return fa[x]= Find(fa[x]);
    }
    void Union(int x, int y)
    {
    	x= Find(x);
    	y= Find(y);
    
    	if (x== y){
    		return;
    	}
    
    	if (rk[x]> rk[y]){
    		fa[y]= x;
    		rk[x]+= rk[y];
    	}
    	else{
    		fa[x]= y;
    		rk[y]+= rk[x];
    	}
    }
    inline double Dist(int i, int j)
    {
    	return i== j ? 0 : sqrt(double((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])));
    }
    double Kruskal(const int n, const int m, int cnt)
    {
    	sort(G, G+m);
    	double ans= 0, minc;
    	int pi;
    
    	for (int i= 0; i< m; ++i){
    		int u= G[i].u, v= G[i].v;
    		int f_u= Find(u), f_v= Find(v);
    		if (f_u== f_v){
    			continue;
    		}
    		ans+= G[i].c;
    		Union(u, v);
    		plan.push_back(pair<int, int>(u, v));
    		if (1== --cnt){
    			break;
    		}
    	}
    
    	return 1== cnt ? ans : -1;
    }
    
    int main(int argc, char const *argv[])
    {
    	int n, m;
    	int u, v;
    	int cnt;
    	scanf("%d", &n);
    	plan.clear();
    	cnt= n;
    	for (int i= 1; i<= n; ++i){
    		scanf("%d %d", x+i, y+i);
    		fa[i]= i;
    		rk[i]= 1;
    	}
    	scanf("%d", &m);
    	for (int i= 0; i< m; ++i){
    		scanf("%d %d", &u, &v);
    		int fa_u= Find(u), fa_v= Find(v);
    		if (fa_u== fa_v){
    			continue;
    		}
    		else{
    			--cnt;
    			Union(fa_u, fa_v);
    		}
    	}
    	m= 0;
    	for (int i= 1; i<= n; ++i){
    		for (int j= i+1; j<= n; ++j){
    			if (Find(i)== Find(j)){
    				continue;
    			}
    			G[m++]= Edge(i, j, Dist(i, j));
    		}
    	}
    	Kruskal(n, m, cnt);
    	for (int i= 0; i< plan.size(); ++i){
    		printf("%d %d
    ", plan[i].first, plan[i].second);
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    SQL常用优化手法
    winform 文件上传
    在主线程中开启同步任务,为什么会阻塞线程
    KVC与KVO
    android shape的使用
    如何导入开源工程
    图片资源的设定
    如何进行程序的反编译和防止反编译
    log的管理
    通过反射机制拿到被隐藏的类(获取应用程序的缓存大小)
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/14657296.html
Copyright © 2011-2022 走看看