zoukankan      html  css  js  c++  java
  • POJ1751

    题目链接

    参考博客:
    https://blog.csdn.net/qq_32680617/article/details/51537339
    https://blog.csdn.net/u013480600/article/details/37969655

    TLE代码

    #include <cstdio>
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define INF 0x7fffffff
    #define N 755
    struct P
    {
    	int x;
    	int y;
    	P():x(0),y(0){}
    };
    struct Edge
    {
    	int u,v;
    	double w;
    	Edge():u(0),v(0),w(0){}
    	bool operator < (const Edge&e)const
    	{
    		return w < e.w;
    	}
    };
    int a[N];
    int rk[N];
    int n;
    int num;
    P nod[N];
    Edge edge[N * N];
    double getDis(int i,int j)
    {
    	double xd = double(nod[i].x - nod[j].x);
    	double yd = double(nod[i].y - nod[j].y);
    	return sqrt(xd * xd + yd * yd);
    };
    void init_edge()
    {
    	int id = 0;
    	int e = n * n;
    	for(int i = 0; i <= e; ++i)
    	{
    		edge[i].w = INF;
    	}
    	for(int i = 1; i <= n; ++i)
    	{
    		for(int j = 1; j <= n; ++j)
    		{
    			id = (i - 1)* n +j;
    			
    			edge[id].u = i;
    			edge[id].v = j;
    			edge[id].w = getDis(i,j);
    			if(i == j) edge[id].w = INF;
    		}
    	}
    }
    void init_set()
    {
    	for(int i = 1; i <= n; ++i)
    	{
    		a[i] = i;
    		rk[i] = 0;
    	}
    }
    int find_set(int x)
    {
    	int p = x;
    	while(a[p] != p)
    	{
    		p = a[p];
    	}
    	int tmp;
    	int now = x;
    	while(now != p)
    	{
    		tmp = a[now];
    		a[now] = p;
    		now = tmp;
    	}
    	return p;
    }
    void union_set(int x,int y)
    {
    	if(rk[x] < rk[y])
    	{
    		a[x] = y;
    	}
    	else
    	{
    		a[y] = x;
    		if(rk[x] == rk[y])
    		{
    			++rk[x];
    		}
    	}
    }
    
    
    void kruskal()
    {
    	int e = n * n;
    	sort(edge,edge + e + 1);
    	int u,v;
    	for(int i = 0; i <= e; ++i)
    	{
    		if(num == 1) break;
    		u = edge[i].u;
    		v = edge[i].v;
    		u = find_set(u);
    		v = find_set(v);
    		if(u != v)
    		{
    			union_set(u,v);
    			--num;
    			printf("%d %d
    ",edge[i].u,edge[i].v);
    		}
    	}
    }
    int main()
    {
    	scanf("%d",&n);
    	num = n;
    	int x,y;
    	for(int i = 1; i <= n; ++i)
    	{
    		scanf("%d%d",&x,&y);
    		nod[i].x = x;
    		nod[i].y = y;
    	}
    	init_edge();
    	int m;
    	scanf("%d",&m);
    	init_set();
    	for(int i = 1; i <= m; ++i)
    	{
    		scanf("%d%d",&x,&y);
    		x = find_set(x);
    		y = find_set(y);
    		if(x != y)
    		{
    			union_set(x,y);
    			--num;
    		}
    	}
    	kruskal();
    	return 0;
    }
    

    超时的原因主要是:
    1.不必要计算出double类型的距离,只需计算x^2 + y^2,达到边之间的比较效果即可,并且数据的约束不会超出int范围 。
    2.n个点需要记录的边数为(n ( imes) (n-1)) (div) 2,而不是n ( imes) n,这样记录边,时间耗费减少一半。

    AC代码

    #include <cstdio>
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define INF 0x7fffffff
    #define N 755
    struct P
    {
    	int x;
    	int y;
    	P():x(0),y(0){}
    };
    struct Edge
    {
    	int u,v;
    	int w;
    	Edge():u(0),v(0),w(0){}
    	bool operator < (const Edge&e)const
    	{
    		return w < e.w;
    	}
    };
    int a[N];
    int rk[N];
    int n;
    int num;
    int edge_num;
    P nod[N];
    Edge edge[N * N];
    int getDis(int i,int j)
    {
    	int xd = (nod[i].x - nod[j].x);
    	int yd = (nod[i].y - nod[j].y);
    	return xd * xd + yd * yd;
    };
    void init_edge()
    {
    	int id = 0;
    	int e = n * n;
    	edge_num = 0;
    	for(int i = 1; i <= n; ++i)
    	{
    		for(int j = i + 1; j <= n; ++j)
    		{
    			edge[edge_num].u = i;
    			edge[edge_num].v = j;
    			edge[edge_num].w = getDis(i,j);
    			++edge_num;
    		}
    	}
    }
    void init_set()
    {
    	for(int i = 1; i <= n; ++i)
    	{
    		a[i] = i;
    		rk[i] = 0;
    	}
    }
    int find_set(int x)
    {
    	int p = x;
    	while(a[p] != p)
    	{
    		p = a[p];
    	}
    	int tmp;
    	int now = x;
    	while(now != p)
    	{
    		tmp = a[now];
    		a[now] = p;
    		now = tmp;
    	}
    	return p;
    }
    void union_set(int x,int y)
    {
    	if(rk[x] < rk[y])
    	{
    		a[x] = y;
    	}
    	else
    	{
    		a[y] = x;
    		if(rk[x] == rk[y])
    		{
    			++rk[x];
    		}
    	}
    }
    
    
    void kruskal()
    {
    	int e = n * n;
    	sort(edge,edge + edge_num);
    	int u,v;
    	for(int i = 0; i < edge_num; ++i)
    	{
    		if(num == 1) break;
    		u = edge[i].u;
    		v = edge[i].v;
    		u = find_set(u);
    		v = find_set(v);
    		if(u != v)
    		{
    			union_set(u,v);
    			--num;
    			printf("%d %d
    ",edge[i].u,edge[i].v);
    		}
    	}
    }
    int main()
    {
    	scanf("%d",&n);
    	num = n;
    	int x,y;
    	for(int i = 1; i <= n; ++i)
    	{
    		scanf("%d%d",&x,&y);
    		nod[i].x = x;
    		nod[i].y = y;
    	}
    	init_edge();
    	int m;
    	scanf("%d",&m);
    	init_set();
    	for(int i = 1; i <= m; ++i)
    	{
    		scanf("%d%d",&x,&y);
    		x = find_set(x);
    		y = find_set(y);
    		if(x != y)
    		{
    			union_set(x,y);
    			--num;
    		}
    	}
    	kruskal();
    	return 0;
    }
    
  • 相关阅读:
    Logging模块
    uWSGI和WSGI区别
    python内置函数getattr用法
    linux 升级python2.7
    JavaScript中判断null、undefined与NaN的方法
    python计算两个数的百分比
    BeautifulSoup中查找元素 select() 和find()区别
    Windows系统以及谷歌浏览器快捷键,控制台常用命令
    自己看源码的一些方法和心得分享
    JDK源码之AbstractStringBuilder类分析
  • 原文地址:https://www.cnblogs.com/lif323/p/9403313.html
Copyright © 2011-2022 走看看