zoukankan      html  css  js  c++  java
  • [luogu6185]序列

    对于2操作,如果把这些操作看成边,那么对于某一个连通块内的若干个点,满足权值可以任意分配(证明:归纳,若n个点可以,那么先将新增的点调整好,再对原来n个点重新分配即可),因此可以将原图缩点,并将连通块的和作为新的权值
    1操作比较复杂,同样把其当成边连起来,形成一张图(包括自环),然后考虑图中的一个连通块
    对这张图,我们可以将操作复杂化:1.对一条长度为奇数的链,两端+1或-1;2.对一条长度为偶数的脸,两端一端+1,一端-1(转化的正确性容易证明)
    如果不存在奇环,那么可以二分图染色,之后相当于左右各是一张2操作的完全图,左右之间点权差不变,即需要满足差值与目标差值相同即可
    如果存在奇环,那么任意两点之间既存在一条奇数边,又存在一条偶数边,所以相当于既是2操作的完全图,又可以让总点权+2,那么只需要和与目标的和奇偶性相同即可

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 100005
     4 struct ji{
     5     int nex,to;
     6 }edge[N<<1];
     7 vector<int>v[3][N];
     8 int E,t,n,m,p,x,y,head[N],bl[N],a[N],b[N],sum[N];
     9 void add(int x,int y){
    10     edge[E].nex=head[x];
    11     edge[E].to=y;
    12     head[x]=E++;
    13 }
    14 void dfs1(int k){
    15     if (bl[k])return;
    16     bl[k]=x;
    17     sum[x]+=a[k]-b[k];
    18     for(int i=0;i<v[2][k].size();i++)dfs1(v[2][k][i]);
    19 }
    20 bool dfs2(int k,int p){
    21     if (bl[k]>=0)return bl[k]==p;
    22     if (p)x+=sum[k];
    23     else y+=sum[k];
    24     bl[k]=p;
    25     bool flag=1;
    26     for(int i=head[k];i!=-1;i=edge[i].nex)flag&=dfs2(edge[i].to,p^1);
    27     return flag;
    28 }
    29 int main(){
    30     scanf("%d",&t);
    31     while (t--){
    32         scanf("%d%d",&n,&m);
    33         E=0;
    34         memset(bl,0,sizeof(bl));
    35         memset(sum,0,sizeof(sum));
    36         memset(head,-1,sizeof(head));
    37         for(int i=1;i<=n;i++)v[1][i].clear();
    38         for(int i=1;i<=n;i++)v[2][i].clear();
    39         for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    40         for(int i=1;i<=n;i++)scanf("%d",&b[i]);
    41         for(int i=1;i<=m;i++){
    42             scanf("%d%d%d",&p,&x,&y);
    43             v[p][x].push_back(y);
    44             v[p][y].push_back(x);
    45         }
    46         x=0;
    47         for(int i=1;i<=n;i++)
    48             if (!bl[i]){
    49                 x++;
    50                 dfs1(i);
    51             }
    52         for(int i=1;i<=n;i++)
    53             for(int j=0;j<v[1][i].size();j++)add(bl[i],bl[v[1][i][j]]);
    54         memset(bl,-1,sizeof(bl));
    55         n=x;
    56         bool flag=1;
    57         for(int i=1;i<=n;i++)
    58             if (bl[i]<0){
    59                 x=y=0;
    60                 p=dfs2(i,0);
    61                 if (p)flag&=(x==y);
    62                 else flag&=((x+y)%2==0);
    63             }
    64         if (flag)printf("YES
    ");
    65         else printf("NO
    ");
    66     }
    67 }
    View Code
  • 相关阅读:
    不务正业系列-浅谈《过气堡垒》,一个RTS玩家的视角
    [LeetCode] 54. Spiral Matrix
    [LeetCode] 40. Combination Sum II
    138. Copy List with Random Pointer
    310. Minimum Height Trees
    4. Median of Two Sorted Arrays
    153. Find Minimum in Rotated Sorted Array
    33. Search in Rotated Sorted Array
    35. Search Insert Position
    278. First Bad Version
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/12608269.html
Copyright © 2011-2022 走看看