题目描述:

这里有 $n$ 个节点和两位大爷,红大爷和蓝大爷。红大爷在坐在节点 $x$ 处,蓝大爷坐在节点 $y$ 处。然后他们各自画了 $n − 1$ 条边,形成了一棵红树和一棵蓝树。

现在大爷们想选择一些节点激活,激活第 $i$ 个节点会带来 $w_i$ 的收益,但是因为两位大爷的树长得不一样,所以他们要先商量一番。

两位大爷都分别开出了一些条件,条件是这样的,这位大爷画出的树上以该大爷所坐的节点为根,节点 $a_i$ 的子树中必须恰有 $b_i$ 个节点被激活。保证红大爷开出的条件中必存在$a_i = x$,同时蓝大爷开出的条件中必存在 $a_i = y$,不保证每位大爷开出的条件不会自相矛盾。如果没看懂请结合样例理解题意。

现在大爷们把你抓了起来,问你能否找到一个方案满足所有的条件,如果存在,输出最大的收益,否则输出 $-1$。

算法标签:费用流

思路:

考虑费用流,对于每一个点计算出最近能限制到我的节点

S连向红大爷的树里有限制的点,流量为限制点数(要减去子树内其他点的限制),费用为 $0$ 。蓝大爷的树里有限制的点连向T。

对于两颗树里的同一个节点,对于这个的节点在两棵树里限制自己的点之间连边,流量为 $1$ ,费用为 $-w[i]$ 。

这样求最小费用流,如果能满流即存在答案,且答案为最小费用的相反数。否则无解。

以下代码:

#include<bits/stdc++.h>
#define il inline
#define _(d) while(d(isdigit(ch=getchar())))
using namespace std;
const int N=1e3+5,inf=1e9;
bool vis[N];
int f[N<<3],c[N<<3],s1,s2,S,T,pre[N],ans,dis[N],w[N];
int n,rt1,rt2,head[N],ne[N<<3],to[N<<3],cnt,g[N],lk[N];
il int read(){int x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch^48;_()x=(x<<1)+(x<<3)+(ch^48);return f*x;
}
il void ins(int x,int y){ne[++cnt]=head[x];head[x]=cnt;to[cnt]=y;
}
il int dfs(int x,int fa,int top){if(g[x])top=x;lk[x]=top;int res=0;for(int i=head[x];i;i=ne[i]){if(fa==to[i])continue;res+=dfs(to[i],x,top);}int tmp=g[x]?g[x]:res;if(g[x])g[x]-=res;if(g[x]<0){puts("-1");exit(0);}return tmp;
}
il void Add(int x,int y,int flow,int cost){ne[++cnt]=head[x];head[x]=cnt;to[cnt]=y;f[cnt]=flow;c[cnt]=cost;
}
il void add(int x,int y,int f,int c){Add(x,y,f,c);Add(y,x,0,-c);
}
il bool spfa(){for(int i=S;i<=T;i++)dis[i]=inf,vis[i]=0,pre[i]=-1;dis[S]=0;vis[S]=1;queue<int> q;q.push(S);while(!q.empty()){int x=q.front();q.pop();vis[x]=0;for(int i=head[x];i!=-1;i=ne[i]){if(dis[to[i]]>dis[x]+c[i]&&f[i]>0){dis[to[i]]=dis[x]+c[i];pre[to[i]]=i;if(!vis[to[i]])vis[to[i]]=1,q.push(to[i]);}}}return dis[T]<inf;
}
il void mcf(){while(spfa()){int mn=inf;for(int i=pre[T];i!=-1;i=pre[to[i^1]])mn=min(mn,f[i]);for(int i=pre[T];i!=-1;i=pre[to[i^1]])f[i]-=mn,f[i^1]+=mn;ans+=dis[T]*mn;s1-=mn;}
}
int main()
{n=read();rt1=read();rt2=read()+n;for(int i=1;i<=n;i++)w[i]=read();for(int i=1;i<n;i++){int x=read(),y=read();ins(x,y);ins(y,x);}for(int i=1;i<n;i++){int x=read()+n,y=read()+n;ins(x,y);ins(y,x);}int Q=read(),a,b;while(Q--)a=read(),g[a]=read();Q=read();while(Q--)a=read()+n,g[a]=read();dfs(rt1,0,rt1);dfs(rt2,0,rt2);cnt=1;S=0;T=(n<<1)+1;for(int i=S;i<=T;i++)head[i]=-1;for(int i=1;i<=n;i++){if(g[i])add(S,i,g[i],0),s1+=g[i];if(g[i+n])add(i+n,T,g[i+n],0),s2+=g[i+n];}for(int i=1;i<=n;i++)add(lk[i],lk[i+n],1,-w[i]);if(s1^s2)return puts("-1"),0;mcf();if(s1)return puts("-1"),0;printf("%d\n",-ans);return 0;
}

View Code

转载于:https://www.cnblogs.com/Jessie-/p/10527877.html

dtoj#4242. 大爷(w)CF1061E相关推荐

  1. mac中Typora+PicGo图床+gitee 保姆级教程

    查看全文 http://www.taodudu.cc/news/show-5900829.html 相关文章: 使用Typora+PicGo+Gitee打造全新Markdown博客创作环境 今天码云( ...

  2. 实用的一条命令(bugbounty tips)

    # 1.提取200状态码连接: cat hosts | urlprobe -c 1000 -t 01 | grep 200 | awk '{print $5}' | tee -a lol-200.tx ...

  3. 【uoj#207】共价大爷游长沙 随机化+LCT维护子树信息

    题目描述 给出一棵树和一个点对集合S,多次改变这棵树的形态.在集合中加入或删除点对,或询问集合内的每组点对之间的路径是否都经过某条给定边. 输入 输入的第一行包含一个整数 id,表示测试数据编号,如第 ...

  4. 【NOI1998】免费馅饼,膜一膜XYX大爷

    免费馅饼 SERKOI最新推出了一种叫做"免费馅饼"的游戏:游戏在一个舞台上进行.舞台的宽度为W格,天幕的高度为H格,游戏者占一格.开始时游戏者站在舞台的正中央,手里拿着一个托盘. ...

  5. 【DTOJ】2701:问候

    DTOJ 2701:问候  解题报告 2017.11.08 第一版 --由翱翔的逗比w原创,引用yzl_rex的CSDN博客 题目信息: 题目描述 问候人类! 输入 输入一行,一个名字,如human( ...

  6. OSChina 周一乱弹 —— 大爷上钩了

    2019独角兽企业重金招聘Python工程师标准>>> Osc乱弹歌单(2018)请戳(这里) [今日歌曲] @胖达panda  :悟空音乐随笔的视频<玉置浩二<melo ...

  7. DTOJ 1486:分数(score)

    DTOJ 1486:分数(score) [题目描述] [输入] 第一行包含两个正整数N和P,表示选手的个数以及精度要求. 接下来的N行,每行包含一个0到100(闭区间)内的整数. [输出] 输出一个实 ...

  8. python 常见的元字符(\d,\w ,^ ,$ 等) 的使用

    python常见的元字符 代码 说明 . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线或汉字 \W 匹配特殊字符,即非字母.非数字.非汉字 \s 匹配任意的空白符 \S 匹配非空白 \d ...

  9. c++ 测试串口速率_Raspberry Pi Zero W:串口(UART)的配置和使用

    Raspberry Pi Zero W:串口(UART)的配置和使用 开启UART 据官方所言(https://www.raspberrypi.org/documentation/configurat ...

最新文章

  1. php yield 导出文件,PHP yield 读取大文件
  2. 黑马程序员--打印流、序列输入流、Vector 类
  3. python 数据分析学什么-如何在业余时学数据分析?
  4. mme设备内部错误_防爆电气设备安装的三大误区 你中招了没?
  5. [javaSE] 多线程(守护线程)
  6. Spring4.x(12)--SpringEL-HelloWorld
  7. docker-compose 使用
  8. STM32 不小心被锁住,解开方法
  9. CMS内容管理系统可行性分析
  10. SpriteKit快速入门和新时代iOS游戏开发指南
  11. 锋麦4S笔记本英伟达独显驱动安装
  12. Hive的行列转换(行转多列、多列转行、行转单列、单列转行)
  13. MySQL学习笔记:upper、lower、ucase、lacase——字符串函数
  14. 聊天界面的制作(三)——表情列表发送功能
  15. 鼠标悬停大小缩略图片切换_3D缩略图悬停效果
  16. ORACLE 按照指定的ID 顺序排序
  17. 因《C程序设计伴侣》的争执,谈谭浩强《C程序设计》的批评
  18. 2023内蒙古大学计算机考研信息汇总
  19. Spring MVC 请求处理过程。你这样回答保证通过面试!
  20. VC6.0 C++ 得到系统时间

热门文章

  1. 一起谈.NET技术,梦想创造可能——盘点微软 .NET 技术八年发展历程
  2. 准备学习下GOOGLE地图
  3. 最新版本UI悬赏任务程序源码
  4. 链路两段不同网段怎么通信_静态路由跨网段访问配置方法和命令
  5. OSChina 周一乱弹 —— 为什么活得很累
  6. 【WinForm】设置TextBox只能输入整数或数字
  7. 大数据Flink End-to-End Exactly-Once
  8. linux下文件或目录是否存在的函数,Linux下的C++程序:判断目录/文件是否存在
  9. 斯坦福大学计算机学什么,斯坦福大学计算机专业课程设置了哪些要学习?入学条件全面解析...
  10. 小白aircrack-ng实战篇