zoukankan      html  css  js  c++  java
  • hdu 1558 Segment set

    点击打开hdu 1558

    思路: 计算几何+并查集
    分析:
    1 有n个操作,最后求有几个集合或者说是连通分量
    2 对于输入一条线段我们就去前面找能够和它相交的线段,利用并查集进行合并并且更新rank数组,rank[x]数组保存的是以x为跟节点的集合的线段的数量
    3 这一题难点就是线段的相交判断

    代码:

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const double eps = 1e-8;
    const double INF = 1<<30;
    const int MAXN = 1010;
    
    struct Node{
        double x1;
        double y1;
        double x2;
        double y2;
    };
    Node node[MAXN];
    
    int n;
    int father[MAXN];
    int rank[MAXN];
    
    void init(int m){
        for(int i = 0 ; i <= m ; i++){
            father[i] = i;
            rank[i] = 1;
        }
    }
    
    int find(int x){
        if(father[x] != x){
            int fa = father[x];
            father[x] = find(fa);
            rank[x] += rank[fa];
        }
        return father[x];
    }
    
    double multiply1(Node a , Node b){
        return (a.x1-a.x2)*(b.y1-a.y1)-(a.y1-a.y2)*(b.x1-a.x1);
    }
    
    double multiply2(Node a , Node b){
        return (a.x1-a.x2)*(b.y2-a.y1)-(a.y1-a.y2)*(b.x2-a.x1);
    }
    
    bool inter(Node a , Node b){
        if(max(a.x1,a.x2) >= min(b.x1,b.x2) &&
                max(b.x1,b.x2) >= min(a.x1,a.x2) &&
                max(a.y1,a.y2) >= min(b.y1,b.y2) &&
                max(b.y1,b.y2) >= min(a.y1,a.y2) &&
                multiply1(a,b) * multiply2(a,b) <= eps &&
                multiply1(b,a) * multiply2(b,a) <= eps)
            return true;
        else return false;
    }
    void solve(){
        for(int i = 1 ; i < n ; i++){
            if(inter(node[i] , node[n])){
                int fx = find(i); 
                int fy = find(n);
                if(fx != fy){
                    father[fy] = fx;
                    rank[fx] += rank[fy];
                }
            }          
        }
    }
    
    int main(){
        int cas , m , k;
        bool isFirst = true;
        char c;
        scanf("%d" , &cas);
        while(cas--){
            if(isFirst)
                isFirst = false;
            else
                puts("");
            n = 1;
            scanf("%d%*c" , &m); 
            init(m);
            while(m--){
                c = getchar(); 
                if(c == 'P'){
                    scanf("%lf" ,&node[n].x1);       
                    scanf("%lf" ,&node[n].y1);       
                    scanf("%lf" ,&node[n].x2);       
                    scanf("%lf%*c" ,&node[n].y2);       
                    if(node[n].x1 > node[n].x2){
                        swap(node[n].x1 , node[n].x2); 
                        swap(node[n].y1 , node[n].y2); 
                    }
                    solve();
                    n++;
                }
                else{
                    scanf("%d%*c" , &k); 
                    int fa = find(k);
                    printf("%d
    " , rank[fa]);
                }
            }
        }
        return 0;
    }
    
    


  • 相关阅读:
    js中split字符串分割
    获取日期,实时显示当前时间,时间相减
    5.5.4 函数内部属性
    单选按钮radio和下拉选择select,ajax返回数据回显对应值
    如何在HTML不同的页面中,共用头部与尾部?
    android-Activity(四大组件之一)
    android-ImageView及其子类
    android-ActionBar
    android- 菜单
    android-Fragment
  • 原文地址:https://www.cnblogs.com/pangblog/p/3253571.html
Copyright © 2011-2022 走看看