【CF1537F】 Figure Fixing 题解
原题链接
如果没看过2020NOI Online序列那道题的话倒是道很有意思的思维题...
Solution
首先我们有一个结论,如果\(\sum v_i -\sum t_i % 2 = 12=1\)为奇数,则一定无解,因为我们每次操作都只会将这个差值偶数倍改动。
下面考虑这个差值是偶数的情况。
因为这张图是联通的,我们任取一棵它的生成树。对于生成树上的叶子结点,我们显然可以通过操作将其需要变化的权值转移到其父节点上,以此类推,最后我们可以将权值全部集中到根节点上。
当一个节点被一个奇环所包括时,我们可以通过改变一圈的操作来达到只改变其中一个节点权值的目的。又因为这是一个无根树,由上面的结论,我们可以推出,只有当图中存在奇环时才有解。
code:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define LL long long
inline void read(int &x){
x=0;
int y=1;
char a;
a=getchar();
while(a<'0'||a>'9'){
if(a=='-')y=-1;
a=getchar();
}
while(a>='0'&&a<='9'){
x=x*10+a-'0';
a=getchar();
}
x*=y;
}
const int N=2e5+5;
struct edge{
int t,nex;
} e[N*2]; int head[N],tot,v[N],t[N];
void add(int x,int y) {
e[++tot].t=y; e[tot].nex=head[x]; head[x]=tot;
}
int T,n,m,color[N],flag=true;
LL sum[3];
void dfs(int x) {
for(int i=head[x];i;i=e[i].nex) {
int y=e[i].t;
if(!color[y]) {
color[y]=3-color[x];
dfs(y);
}
else {
if(color[y] == color[x]) flag=false;
}
}
}
void solve() {
for(int i=1;i<=n;i++) sum[0]+=t[i]-v[i];
sum[0]=abs(sum[0]);
if(sum[0] & 1) {
printf("NO\n");
return;
}
color[1]=1;
dfs(1);
if(!flag) {
printf("YES\n");
return;
}
for(int i=1;i<=n;i++) sum[color[i]]+=t[i]-v[i];
if(sum[1] == sum[2]) printf("YES\n");
else printf("NO\n");
}
int main(){
read(T);
while(T--) {
tot=0; flag=true;
memset(head,0,sizeof(head));
memset(sum,0,sizeof(sum));
memset(color,0,sizeof(color));
read(n); read(m);
for(int i=1;i<=n;i++) read(v[i]);
for(int i=1;i<=n;i++) read(t[i]);
int x,y;
for(int i=1;i<=m;i++) {
read(x); read(y);
add(x,y); add(y,x);
}
solve();
}
return 0;
}

浙公网安备 33010602011771号