建立二分图,首先如果存在度数为$0$的点,那么显然无解。

如果存在度数为$1$的点,那么这个点的匹配方案固定,可以通过拓扑排序去掉所有这种点。

那么现在剩下的点度数都至少为$2$,因为左右点数相等,且左边每个点度数都是$2$,所以右边只能是每个点的度数都是$2$。

在这种情况下每个连通块是一个环,相邻两条边不能同时选,一共有两种情况$x$和$y$。

假设$x\leq y$,那么把$x$加入$sum$,$y-x$既可以加入,又可以不加入,对$y-x$进行01背包即可。

注意到本题中物品数不超过$2n$,物品价值之和不超过$2k\leq 40n$。

所以将01背包转化为多重背包后只有$O(\sqrt{k})$种物品,二进制拆分+bitset优化即可。

时间复杂度$O(\frac{k\sqrt{k}\log k}{64})$。

#include<cstdio>
#include<bitset>
#include<algorithm>
using namespace std;
const int N=120010,M=1200010;
int n,m,K,i,j,k,x,y,z,g[N],v[N<<1],w[N<<1],nxt[N<<1],ed,d[N],h,t,q[N],vis[N],sum,cnt[M];
bitset<M>f;
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
inline void add(int x,int y,int z){
d[x]++,d[y]++;
v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;
v[++ed]=x;w[ed]=z;nxt[ed]=g[y];g[y]=ed;
}
inline int go(int x){
for(int i=g[x];i;i=nxt[i])if(!vis[v[i]])return v[i];
return 0;
}
inline int get(int x,int y){for(int i=g[x];i;i=nxt[i])if(v[i]==y)return w[i];}
int main(){
read(n),read(K);m=n+n;
for(i=1;i<=m;i++){
read(x),read(y),read(z);
add(i,x+m,z);
add(i,y+n+m,-z);
}
m<<=1;
for(i=1;i<=m;i++)if(!d[i])return puts("NO"),0;
for(h=i=1;i<=m;i++)if(d[i]==1)q[++t]=i;
while(h<=t){
for(i=g[x=q[h++]];i;i=nxt[i])if(!vis[v[i]]){
y=v[i];
sum+=w[i];
break;
}
vis[x]=vis[y]=1;
for(i=g[y];i;i=nxt[i])if(!vis[x=v[i]]){
if(!(--d[x]))return puts("NO"),0;
if(d[x]==1)q[++t]=x;
}
}
for(n=0,i=1;i<=m;i++)if(!vis[i]){
vis[q[t=1]=i]=1;
for(j=go(i);j;j=go(j))vis[q[++t]=j]=1;
q[t+1]=q[1];
x=y=0;
for(j=1;j<=t;j+=2)x+=get(q[j],q[j+1]);
for(j=2;j<=t;j+=2)y+=get(q[j],q[j+1]);
if(x>y)swap(x,y);
sum+=x;
cnt[y-x]++;
n=max(n,y-x);
}
for(f[0]=i=1;i<=n;i++)for(j=1;cnt[i];j<<=1){
k=min(cnt[i],j);
cnt[i]-=k;
f|=f<<(i*k);
}
for(i=-K;i<=K;i++)if(i-sum>=0&&i-sum<M)if(f[i-sum])return puts("YES"),0;
return puts("NO"),0;
}

  

BZOJ4124 : [Baltic2015]Tug of war的更多相关文章

  1. HDU-2576 Tug of War

    http://poj.org/problem?id=2576 二维数组01背包的变形. Tug of War Time Limit: 3000MS   Memory Limit: 65536K Tot ...

  2. 随机算法 poj 2576 Tug of War

    Tug of War Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 8187   Accepted: 2204 Descri ...

  3. UVA - 10032 Tug of War (二进制标记+01背包)

    Description Problem F: Tug of War A tug of war is to be arranged at the local office picnic. For the ...

  4. uva 10032 Problem F: Tug of War

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  5. zoj 1880 - Tug of War

    题目:有n个人分成两组,两组人数差不能超过1,找到两组的人重量之差的最小值. 分析:dp,二维01背包. 由于必须放在两个组中的一组,直接背包全部可到状态, 取出相差不超过 1的最接近 sum/2的值 ...

  6. POJ2576 Tug of War 二维背包

    题目大意 一群人拔河,给出每个人的重量,要求两队人数之差不超过1人,且每队总重量之差最小. 思路 选出严格总人数一半(或+1)的人为一队,在该队重量不超过所有人总重量一半的情况下,使其重量最大. 人数 ...

  7. poj 2576 Tug of War

    还是神奇的随机算法,,(看视频说这是爬山法??) 其实就是把序列随机分成两半(我太弱,只知道random_shuffle),然后再每个序列里rand一个位置,x,y然后比较是不是交换之后是更优的. 然 ...

  8. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  9. 动态规划:POJ2576-Tug of War(二维费用的背包问题)

    Tug of War Time Limit: 3000MS Memory Limit: 65536K Description A tug of war is to be arranged at the ...

随机推荐

  1. 常用css样式(布局)

    兼容css3新属性 在css3中,我们可以使用prefixfree.min.js这个插件来自动为css3的相关属性加上兼容浏览器属性,使我们不用为每个css3新属性再加上属性(需要用到大量css3的项 ...

  2. crontab定时作业

    crontab用于在指定时间执行某项作业,如执行脚本或命令. 1.crontab -e      创建一个crontab文件,并添加作业(这个crontab的拥有者是创建者). 这里要注意:必须指定s ...

  3. 【转】C++ map的基本操作和使用

    1.map简介 map是一类关联式容器.它的特点是增加和删除节点对迭代器的影响较小,除了那个操作节点,对其它的节点都没有什么影响.对于迭代器来说,可以修改实值,而不能修改key. 2.map的功能 自 ...

  4. [学习笔记]Javascript采用二进制浮点数和四舍五入的错误

    1.样例 var a = .3 - .2 //0.09999999999999998 var b = .2 - .1 //0.1 a == b //false 出现这样的原因在于 1.Javascri ...

  5. Python-html css 盒模型

    <!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>ht ...

  6. jQuery实现鼠标点击div外的地方div隐藏消失的效果

    css部分: <style type="text/css"> .pop { width:200px; height:130px; background:#080;} & ...

  7. [转]CentOS7 下安装svn

    1. 安装 centos(我这里使用的是CentOS7)下yum命令即可方便的完成安装 $ sudo yum install subversion 测试安装是否成功: $ svnserve --ver ...

  8. 树链剖分边权模板spoj375

    树链剖分是树分解成多条链来解决树上两点之间的路径上的问题 如何求出树链:第一次dfs求出树上每个结点的大小和深度和最大的儿子,第二次dfs就能将最大的儿子串起来并hash(映射)到线段树上(或者其他数 ...

  9. MySQL索引底层实现原理

    优秀博文: MySQL索引背后的数据结构及算法原理 B树.B-树.B+树.B*树[转],mysql索引 MySQL 和 B 树的那些事 索引的本质 MySQL官方对索引的定义为:索引(Index)是帮 ...

  10. NOI 2012 随机数生成器

    看到全是矩阵的题解,我来一发递推+分治 其实这题一半和poj1845很像(或是1875?一个叫Sumdiv的题) 言归正传,我们看看怎么由f(0)推出f(n) 我们发现,题目中给出了f(n)=af(n ...