• poj 1182--食物链 (并查集)


    题目链接:https://vjudge.net/contest/220024#problem/E

    题目没大意(中文题,哪里还用得到大意)

    在原始的基础上,需要考虑到三者的关系维护,还有就是千万不要用C++的输入输出流读取,因为数据量大,时间上会超限

    维护的时候首先要考虑反情况(范围外,吃与被吃的关系),如果不存在反情况的话,那么就可以认为这种情况是正确的,

    那接下来的做法就是把正确的情况更新一下,吃,被吃和同类的三个关系同时更新一下;如果存在反情况的话,就把定义储

    存反情况的数目更新一下即可, 不废话了,还是看代码吧。

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <algorithm>
    using namespace std;
    #define MAX_N 51000
    
    
    int f[4 * MAX_N];
    int n, k;
    int d, x, y;
    
    int geft(int x)
    {
        while(x != f[x])
            x = f[x];
        return x;
    }
    
    void finds(int u, int v)
    {
        f[geft(v)] = geft(u);
    }
    ///f[x]储存同类  f[x+n]储存吃x的  f[x+2*n]储存被x吃的
    
    bool pan1(int x,int y)/// 判断x和y是同类是不是真话?
    {
        if(x<=0 || x>n || y<=0 || y>n)
            return false;
        if(geft(y) == geft(x+n))
            return false;
        if(geft(y) == geft(x+2*n))
            return false;
        return true;
    }
    
    bool pan2(int x,int y)/// 判断x吃y是不是真话?
    {
        if(x<=0 || x>n || y<=0 || y>n)
            return false;
        if(geft(x) == geft(y))
            return false;
        if(geft(y) == geft(x+2*n))
            return false;
        return true;
    }
    
    int main()
    {
        int i, j;
        int ans = 0;
        scanf("%d%d", &n, &k);
        for(i=1;i<=4*n;i++)
            f[i] = i;
        for(i=0; i<k; i++)
        {
            scanf("%d%d%d", &d, &x, &y);
            if(x<=0 || x>n || y<=0 || y>n)
            {
                ans++;
                continue;
            }
            if(d == 1)///判断是不是同类
            {
                if(pan1(x, y))
                {
                    finds(x, y);
                    finds(x+n, y+n);
                    finds(x+2*n, y+2*n);
                }
                else
                    ans++;
            }
            else
            {
                if(pan2(x,y))
                {
                    finds(x+n, y);
                    finds(x, y+2*n);
                    finds(y+n,x+2*n);
                }
                else
                    ans++;
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

    (说不采用C++的输入输出流,还是在不时间超限的基础上,用上了输出的方式,没办法,挺方便的,就是耗时长了一点)

  • 相关阅读:
    正则表达式在行首添加指定内容
    linux之find命令详解
    一次安装rpcbind失败引发的思考
    配置linux实现路由功能
    chkconfig命令详解
    1225 数数字
    蛇形填数 ------- 模拟水题
    开灯问题---------简单模拟
    单源最短路径
    图的表示方式
  • 原文地址:https://www.cnblogs.com/zznu17-091041/p/8732377.html
Copyright © 2020-2023  润新知