zoukankan      html  css  js  c++  java
  • 【NOI2001】食物链

    一道“扩展域”并查集的题目,我们把每一个点拆分成三个域:同类、食物、天敌。

    我们假设x的同类域为x,食物域为x+n,天敌域为x+n+n。假设x与y是同类,那么说明x+n与y+n是同类,x+n+n与y+n+n是同类。

    假设x吃y,那么x+n与y是同类,x+n+n与y+n是同类,x与y+n+n是同类。

    现在我们只需要判断一句话与之前处理的关系是否冲突即可,如果不冲突,就按照上面的同类关系合并即可;冲突则统计答案。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 int n,m;
     6 int f[50010*3];
     7 int find(int x) {
     8     if(f[x]!=x) f[x]=find(f[x]);
     9     return f[x];
    10 }
    11 void add(int x,int y) {
    12     f[find(x)]=find(y);
    13 }
    14 int main() {
    15     cin>>n>>m;
    16     for(int i=1;i<=n*3;i++) f[i]=i;
    17     int ans=0;
    18     for(int i=1;i<=m;i++) {
    19         int op,x,y;
    20         cin>>op>>x>>y;
    21         if(x>n||y>n) {
    22             ans++;
    23             continue ;
    24         }
    25         if(op==1) {
    26             if(find(x)==find(y+n)||find(x)==find(y+n+n)) ans++;
    27             else {
    28                 add(x,y);
    29                 add(x+n,y+n);
    30                 add(x+n+n,y+n+n);
    31             }
    32         }
    33         else if(op==2) {
    34             if(find(x)==find(y)||find(x)==find(y+n)) ans++;
    35             else {
    36                 add(x,y+n+n);
    37                 add(x+n,y);
    38                 add(x+n+n,y+n);
    39             }
    40         }
    41     }
    42     cout<<ans<<endl;
    43     return 0;
    44 }
    AC Code
  • 相关阅读:
    3.25训练题
    hdu1495
    poj1426 宽搜
    高斯消元
    codeforces 999E 强联通分量
    hdu4289城市与歹徒 网络流
    蒟蒻的离散化模板
    樱花,素数筛
    【转】分圆问题:一个诡异的数列规律
    hdu1257最少拦截系统 贪心
  • 原文地址:https://www.cnblogs.com/shl-blog/p/10803795.html
Copyright © 2011-2022 走看看