Codeforces Round #726 (Div. 2)F. Figure Fixing题解

题目链接:F. Figure Fixing
思路:首先我们发现如果\(\sum t_i-v_i\)为奇数,那么一定\(NO\),因为每次改变时是一条边两头改变,改变数总是偶数,所以奇数绝对不行,因为他问的是在进行了若干次操作之后能否可行的问题,所以我们可以通过找到最小变化量来解决该问题,这应该是个构造问题。再次分析发现如果存在奇环就一定可以。 我们随便选一张图可以发现:

图1
只要联通我们就可以通过若干次选择将所有点的权值集中到任意一个点上如上图所示,我们可以通过边\((F,E)\)\(F\)的点权清零,然后通过\((E,D)\)\(E\)的点权清零,这样操作,\(E,F,D\)上的所有点权都集中在了\(D\)上,并且该操作也是可逆的。那么因为该图是联通图,第一步我们可以将所有权值以这样的形式移动到一个奇环上,接下来:

其中边权是指操作该边使该边两端节点加上某一个值,发现这样一趟下来,只有一个点点权增加了2,其余点权皆不受影响,这样一来我们就可以通过若干次这种操作将整张图清0。然后如果没有奇环,那么该图是二分图,因为二分图内部没有边连接,操作一条边的结果只可能是二分图两边增加或减少,换句话说,两边增量保持相等,所以只需要保证两边需求增量相同就一定有一种构造方法。
\(Code:\)


#include<set>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<map>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#define ll long long
#define ull unsigned long long
#define pb emplace_back
#define mp make_pair
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define bep(i,a,b) for(int i=a;i>=b;--i)
#define lowbit(x) (x&(-x))
#define ch() getchar()
#define pc(x) putchar(x)
using namespace std;

template<typename T>void read(T&x){
static char c;static int f;
for(c=ch(),f=1;c<'0'||c>'9';c=ch())if(c=='-')f=-f;
for(x=0;c>='0'&&c<='9';c=ch())x=x*10+(c&15);x*=f;
}
template<typename T>void write(T x){
static char q[65];int cnt=0;
if(x<0)pc('-'),x=-x;
q[++cnt]=x%10,x/=10;
while(x)
	q[++cnt]=x%10,x/=10;
while(cnt)pc(q[cnt--]+'0');
}


const int N = 2e5+10;
vector<int>G[N];
int n,m,col[N];
int _;
int dis[N];
int x;
bool flag ;
void dfs(int x,int color){
    col[x] = color;
    for(auto p:G[x]){
        if(col[p] == color)flag = true;
        if(col[p])continue;
        dfs(p,-color);
    }
}
void init(){rep(i,1,n)G[i].clear(),col[i] = 0; }
void solve(){
    read(_);
    while(_--){
        flag = false;

        read(n);read(m);
        rep(i,1,n)read(dis[i]);
        init();
        ll sum = 0ll;
        rep(i,1,n)read(x),dis[i] = x-dis[i],sum += 1ll*dis[i];
        rep(i,1,m){
            int u,v;
            read(u);read(v);
            G[u].pb(v);G[v].pb(u);
        }
        dfs(1,1);ll ans = 0ll;
        rep(i,1,n){
            if(col[i] == 1)ans+=1ll * dis[i];
        }
        if(flag == false and ans == sum - ans)flag = true;
        if(sum % 2)flag = false;
        if(flag)puts("YES");else puts("NO");


    }
}

signed main(){solve();return 0; }



posted @ 2021-07-03 09:18  xiaodangao  阅读(119)  评论(0编辑  收藏  举报