这道题先建图,然后把联通子块染色,一个联通子块染成两个颜色,然后01背包就可。
如果总和为2X,那么每个连通子块小的那个加起来后的和为Y,那么(X-Y)就是剩下的可以操作的空间,然后求每个联通子块两个部分的差值b[MAX_V],在(X-Y)里做b[MAX_V]的01背包,求一个最大值dp[m],再加上(X-Y)就是其中一个的值,然后用总的输出max(sum-(X-Y)-dp[m],(X-Y)+dp[m])。
因为每个值都是100的倍数,所以一开始可以把值除以100。
#include<bits/stdc++.h>
using namespace std;
struct Node{
int v,nxt;
}e[450];
int head[220];
int vis[220];
int a[220];
int b[220];
int si,top;
int dp[100000];
void add(int u,int v){
e[top].v=v;
e[top].nxt=head[u];
head[u]=top++;
}
void dfs(int x,int op){
vis[x]=op+si