sgu174

1 篇文章 0 订阅
1 篇文章 0 订阅
    题目大意就是给你N条线段,然后按照顺序添加线段,求出当添加入第几条线段时,已添加的某些线段组成了一个回路。

    题意很好理解,算法也很容易出来,只要在添加某一条线段时,该线段的两个端点在之前就已经相连,那么加入这个线段后,就必然形成了一个回路。

    判断这些点的联通性,一个算法呼之欲出,那就是并查集。可以给每个出现过的点一个编号,然后按照这个编号进行并查集即可。

 

    比较恶心的地方就是给这个点添加编号,由于点是两维的,离散起来比较恶心,写平衡树也很恶心,那么我们就只能发挥C++的优势,使用字典的完美模型——map。不知道map的可以去翻翻c++ primer.里面写的很清楚。

    只要设置一个pair代表点,在设置一个map代表点到编号的映射就可以了。

    typedef pair<int,int> point;

    map<point,int> point_map;

    下面是我的代码。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <map>

using namespace std;

const int maxn = 4000010;
typedef pair<int,int> point;
typedef map<point,int>::value_type insert_val;
map<point,int> point_map;
int father[maxn];
int point_num,check_p1,check_p2;

int getfather(int p){
    if (father[p] == p)
	return p;
    return (father[p]=getfather(father[p]));
}
int main(){
    int i,j,k,n;
    scanf("%d\n",&n);
    for (i=1;i<=n;++i){
	point p1,p2;
	scanf("%d%d%d%d\n",&p1.first,&p1.second,&p2.first,&p2.second);

	check_p1 = point_map.count(p1);
	check_p2 = point_map.count(p2);
	if (!check_p1){
	    point_map.insert(insert_val(p1,++point_num));
	    father[point_num] = point_num;
	}
	if (!check_p2){
	    point_map.insert(insert_val(p2,++point_num));
	    father[point_num] = point_num;
	}
	
	
	int p1_num = point_map[p1];
	int p2_num = point_map[p2];
	
	int p1_father = getfather(p1_num);
	int p2_father = getfather(p2_num);
	
	if (p1_father == p2_father){
	    printf("%d\n",i);
	    return 0;
	}else
	    father[p1_father] = p2_father;
    }
    printf("0\n");
    return 0;
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值