zoukankan      html  css  js  c++  java
  • luogu P6185 [NOI Online 提高组]序列 并查集缩点 二分图

    首先现在操作2,一个+1,一个-1。就好比权值可以在两点之间流动。我们发现,把操作2当作边,则一个联同的子图,内部的权值是可以随便流动的。我们就这个把这个子图看多一个点。这个我们用并查集来实现。那么这个并查集内的s[i]也对应求和。

    我们把操作2,都处理完了,我们再考虑操作2。对于操作1,我们连边,注意此时的点已经缩小过。我们可以发现,如果一个联同子图,是二分图,则可以作到,两个部分在差不变的情况下,变成任意值。就是如果两个部分的s[i]的和相同,减去同样的差,变为0,则可以。如果一个联通子图,不是二分图,那么我们可以作到,总的奇偶性不变下,任意加减。就是如果总的s[i]的和为偶数,则可以变为0,则可行。

    这题判断奇偶可能有负数,闲的写了个%2==1,找了2个小时.....

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 using namespace std;
      5 typedef long long ll;
      6 ll s[210000],sum[3];
      7 int n,m,ans,T,a[210000],b[210000],fa[210000],siz[210000],qry[210000][2],col[210000];
      8 int ecnt,cnt,head[210000],nxt[420000],to[420000];
      9 void add(int x,int y)
     10 {
     11     nxt[++ecnt] = head[x];
     12     to[ecnt] = y;
     13     head[x] = ecnt;
     14 }
     15 int getfa(int x)
     16 {
     17     if (fa[x] == x)
     18         return x;
     19     return fa[x] = getfa(fa[x]);
     20 }
     21 void merge(int x,int y)
     22 {
     23     int s1 = getfa(x),s2 = getfa(y);
     24     if (s1 == s2)
     25         return;
     26     if (siz[s1] < siz[s2])
     27     {
     28         fa[s1] = s2;
     29         siz[s2] += siz[s1];
     30     }else
     31     {
     32         fa[s2] = s1;
     33         siz[s1] += siz[s2];
     34     }
     35 }
     36 bool dfs(int x,int k)
     37 {
     38     col[x] = k;
     39     sum[k] += s[x];
     40     bool suc = true;
     41     for (int i = head[x];i;i = nxt[i])
     42     {
     43         if (col[to[i]] == col[x])
     44             suc = false;
     45         if (col[to[i]] == 0 && dfs(to[i],3 - k) == false)
     46             suc = false;
     47     }
     48     return suc;
     49 }
     50 int main()
     51 {
     52     for (scanf("%d",&T);T;T--)
     53     {
     54         for (int i = 1;i <= ecnt;i++)
     55             nxt[i] = 0;
     56         cnt = ecnt = 0;
     57         ans = 1;
     58         scanf("%d%d",&n,&m);
     59         for (int i = 1;i <= n;i++)
     60             s[i] = col[i] = head[i] = 0;
     61         for (int i = 1;i <= n;i++)
     62             scanf("%d",&a[i]);
     63         for (int i = 1;i <= n;i++)
     64             scanf("%d",&b[i]);
     65         for (int i = 1;i <= n;i++)
     66             fa[i] = i,siz[i] = 1;
     67         int topt,tx,ty;
     68         for (int i = 1;i <= m;i++)
     69         {
     70             scanf("%d%d%d",&topt,&tx,&ty);
     71             if (topt == 2)
     72                 merge(tx,ty);
     73             else
     74             {
     75                 qry[++cnt][0] = tx;
     76                 qry[cnt][1] = ty;
     77             }
     78         }
     79         for (int i = 1;i <= n;i++)
     80             s[getfa(i)] += b[i] - a[i];
     81         for (int i = 1;i <= cnt;i++)
     82         {
     83             add(getfa(qry[i][0]),getfa(qry[i][1]));
     84             add(getfa(qry[i][1]),getfa(qry[i][0])); 
     85         }
     86         for (int i = 1;i <= n;i++)
     87         {
     88             if (getfa(i) != i || col[i])
     89                 continue;
     90             sum[1] = sum[2] = 0;
     91             bool suc = dfs(i,1);
     92             if (suc && sum[1] != sum[2])
     93             {
     94                 ans = 0;
     95                 break;
     96             }
     97             if (!suc && ((sum[1] + sum[2]) & 1))
     98             {
     99                 ans = 0;
    100                 break;
    101             }
    102         }
    103         printf("%s
    ",ans ? "YES" : "NO"); 
    104     }
    105 }
  • 相关阅读:
    美团霸面---我想说说心里话。
    docker在ubuntu14.04下的安装笔记
    ubuntu14.04 upgrade出现【Ubuntu is running in low-graphics mode】问题的一个解决办法
    Python2和Python3在windows下共存
    Python发送邮件
    Python在安装第三方模块遇到的问题及解决办法
    127.0.0.1和localhost完全相等吗?
    vim总结
    linux shell学习笔记
    Jenkins +JUnit
  • 原文地址:https://www.cnblogs.com/iat14/p/12495257.html
Copyright © 2011-2022 走看看