zoukankan      html  css  js  c++  java
  • [agc016E]Poor Turkeys

    Description

    传送门

    Solution

    如果真的按照题目要求一对对的考虑好麻烦的。。(我场上就没嗑出来)

    我们定义集合ai,假如鸡i要存活,则它需要哪一些鸡在它和i相关的鸡同时被拎出来前存活。

    可能定义看得人有点晕。。是这样,初始时ai里只有i。则我们要求所有和i同时被拎出来过的鸡,在和i同时被拎出来前存活,将这些点加到ai里。

    然后ai里的每一个点都按上述方式扩展直到无法扩展,实现用dfs就好。(假如在扩展中某一个节点已经在集合a中的时候又被访问到则鸡i一定会被吃,证明显然)

    我们枚举鸡i和j。假如要i和j都同时存活,则ai和aj之间必须没有任何相同的点。否则假如有点x在两个集合中都有出现,那么按照时间顺序,当它为满足i或j某只鸡的存活而被吃后,必定有另一只鸡的a集合是无法全部满足的。

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    const int inf=1e9;
    int n,m,x,y;
    struct node{int y,id,nxt;
    }g[200010];int h[410],tot=0;
    void _link(int x,int y,int id){g[++tot]=node{y,id,h[x]};h[x]=tot;}
    int pre[410][410];
    bool might_alive[410];
    void dfs(int x,int id)
    {
        if (!might_alive[id]) return;
        for (int i=h[x];i;i=g[i].nxt)
        if (g[i].id<pre[id][x])
        {
            if(pre[id][g[i].y]) might_alive[id]=0;
            pre[id][g[i].y]=g[i].id;
            dfs(g[i].y,id);
        }
    }
    int ans=0;
    bool _is;
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            _link(x,y,i);_link(y,x,i);
        }
        for (int i=1;i<=n;i++) might_alive[i]=1,pre[i][i]=inf,dfs(i,i);
        
        int c;
        for (int i=1;i<n;i++) if (might_alive[i])
            for (int j=i+1;j<=n;j++) if (might_alive[j])
            {
                for (_is=0,c=1;c<=n;c++) 
                if (pre[i][c]&&pre[j][c]) {_is=1;break;}
                if (!_is) ans++;            
            }
    
        cout<<ans;
    }
  • 相关阅读:
    [ 低危 ] mt网CRLF
    mysql之字段的修改,添加、删除,多表关系(外键),单表详细操作(增删改)
    mysql 之编码配置、引擎介绍、字段操作、数据类型及约束条件
    Navicat Premium永久激活方式
    centos 用户名密码忘记了怎么办?
    并发编程总结
    初识mysql
    线程queue、线程进程池,协程
    python解释器
    线程全局修改、死锁、递归锁、信号量、GIL以及多进程和多线程的比较
  • 原文地址:https://www.cnblogs.com/coco-night/p/9531955.html
Copyright © 2011-2022 走看看