【NOI2008】志愿者招募

【2017山东day7】养猫做法类似。

都是神仙题。

首先我设\(c_{i,j}=[l[j]\leq i\leq r[j]]\) ,于是就可以列出下面的不等式:

\[\displaystyle
\begin{align}
\sum_{i=1}^mc_{1,i}*d_i&\geq a_1\\
&...\\
\sum_{i=1}^mc_{n,i}*d_i&\geq a_n\\
0&=0
\end{align}
\]

我们加一个辅助变量\(y_i\),使不等式变成等式,并且在最后加上\(0=0\):

\[\displaystyle
\begin{align}
\sum_{i=1}^mc_{1,i}*d_i&=y_1+a_1\\
&...\\
\sum_{i=1}^mc_{n,i}*d_i&=y_n+a_n\\
0&=0
\end{align}
\]

差分后:

\[\begin{align}
\displaystyle
\sum_{i=1}^mc_{1,i}*d_i&=y_1+a_1\\
\sum_{i=1}^mc_{2,i}*d_i+y_1+a_1&=\sum_{i=1}^mc_{1,i}*d_i+y_2+a_2\\
&...\\
\sum_{i=1}^mc_{n,i}*d_i+y_{n-1}+a_{n-1}
&=\sum_{i=1}^mc_{n-1,i}*d_i+y_n+a_n\\
y_n+a_n&=\sum_{i=1}^mc_{n,i}*d_i
\end{align}
\]

然后每个变量就会在等式左边和右边各出现一次。对于一个变量\(x\),我们从它出现于右边的等式连一条边到它出现于左边的等式。对于常量,它出现在左边就从\(S\)连一条边到该等式,否则该等式连一条边到\(T\)。

代码:

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. #define N 2005
  4. #define M 20005
  5. using namespace std;
  6. inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
  7. int n,m;
  8. int S,T;
  9. int l[M],r[M],c[M];
  10. int a[N];
  11. struct road {
  12. int to,next;
  13. int flow;
  14. ll cost;
  15. }s[(N+M)*5];
  16. int h[N],cnt=1;
  17. void add(int i,int j,int f,ll c) {
  18. s[++cnt]=(road) {j,h[i],f,c};h[i]=cnt;
  19. s[++cnt]=(road) {i,h[j],0,-c};h[j]=cnt;
  20. }
  21. ll ans=0;
  22. ll tag[N];
  23. ll lim[N];
  24. ll dis[N];
  25. int fr[N],e[N];
  26. bool in[N];
  27. queue<int>q;
  28. int tot;
  29. int maxflow;
  30. bool ins[N];
  31. int dfs(int v,int maxf) {
  32. if(v==T) return maxf;
  33. ins[v]=1;
  34. int ret=0;
  35. for(int i=h[v];i;i=s[i].next) {
  36. int to=s[i].to;
  37. if(!ins[to]&&s[i].flow&&dis[to]==dis[v]+s[i].cost) {
  38. int dlt=dfs(to,min(maxf,s[i].flow));
  39. ret+=dlt;
  40. s[i].flow-=dlt;
  41. s[i^1].flow+=dlt;
  42. maxf-=dlt;
  43. if(!maxf) return ins[v]=0,ret;
  44. }
  45. }
  46. ins[v]=0;
  47. return ret;
  48. }
  49. ll dinic() {
  50. ll ans=0;
  51. while(1) {
  52. int tem=dfs(S,1e9);
  53. if(!tem) break;
  54. ans+=tem;
  55. }
  56. return ans;
  57. }
  58. bool spfa() {
  59. memset(dis,0x3f,sizeof(dis));
  60. dis[S]=0;
  61. q.push(S);
  62. while(!q.empty()) {
  63. int v=q.front();
  64. q.pop();
  65. in[v]=0;
  66. for(int i=h[v];i;i=s[i].next) {
  67. int to=s[i].to;
  68. if(s[i].flow&&dis[to]>dis[v]+s[i].cost) {
  69. dis[to]=dis[v]+s[i].cost;
  70. fr[to]=v;
  71. e[to]=i;
  72. if(!in[to]) in[to]=1,q.push(to);
  73. }
  74. }
  75. }
  76. if(dis[T]>1e9) return 0;
  77. ans+=dinic()*dis[T];
  78. return 1;
  79. }
  80. int main() {
  81. n=Get(),m=Get();
  82. for(int i=1;i<=n;i++) a[i]=Get();
  83. for(int i=1;i<=m;i++) l[i]=Get(),r[i]=Get(),c[i]=Get();
  84. T=n+2;
  85. for(int i=1;i<=n;i++) {
  86. add(i,T,a[i],0);
  87. add(S,i+1,a[i],0);
  88. add(i,i+1,1e9,0);
  89. }
  90. for(int i=1;i<=m;i++) {
  91. add(r[i]+1,l[i],1e9,c[i]);
  92. }
  93. while(spfa());
  94. cout<<ans;
  95. return 0;
  96. }

【NOI2008】志愿者招募的更多相关文章

  1. BZOJ 1061: [Noi2008]志愿者招募

    1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 4064  Solved: 2476[Submit][Stat ...

  2. BZOJ 1061: [Noi2008]志愿者招募 [单纯形法]【学习笔记】

    1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3975  Solved: 2421[Submit][Stat ...

  3. [BZOJ1061][Noi2008]志愿者招募

    [BZOJ1061][Noi2008]志愿者招募 试题描述 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难 题:为即将启动的奥运新项目招募一批短期志愿 ...

  4. BZOJ 1061: [Noi2008]志愿者招募 费用流

    1061: [Noi2008]志愿者招募 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1061 Description 申奥成功后,布布 ...

  5. bzoj1061: [Noi2008]志愿者招募

    线性规划与费用流.http://www.cnblogs.com/iiyiyi/p/5616080.html.数组范围开错了!!!然后2.31-1=0x7fffffff!=0x7f7f7f7f. 开始以 ...

  6. NOI2008 志愿者招募

    1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1859  Solved: 1169[Submit][Stat ...

  7. 线性规划||网络流(费用流):COGS 288. [NOI2008] 志愿者招募

    [NOI2008] 志愿者招募 输入文件:employee.in   输出文件:employee.out   简单对比 时间限制:2 s   内存限制:512 MB [问题描述] 申奥成功后,布布经过 ...

  8. 从[NOI2008志愿者招募]浅谈线性规划在网络流构图上的巧用

    首先来看一下题..http://www.lydsy.com/JudgeOnline/problem.php?id=1061 1061: [Noi2008]志愿者招募 Description 申奥成功后 ...

  9. 【费用流】BZOJ1061: [Noi2008]志愿者招募(这题超好)

    1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 5291  Solved: 3173[Submit][Stat ...

  10. BZOJ 1061: [Noi2008]志愿者招募【单纯形裸题】

    1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 4813  Solved: 2877[Submit][Stat ...

随机推荐

  1. asp .net core Get raw request.

      小弟初来乍到,分享一些工作学习中遇到的问题和解决方式,如有不准确或是有错误的地方,希望不吝赐教,谢过了.  --Dogtwo 背景: 一个代理服务器BK,接收前端A发送的请求,记录log,并转发给 ...

  2. BurpSuite 各模块使用

    Proxy  代理 对浏览器进行代理 对浏览器增加代理服务器 可以对http 请求进行监视 intercept is on 进行监控  off 不监控 可以任意修改 对任意的网络请求 进行爬虫 在 s ...

  3. 微信小程序实现支付功能

    小程序支付,没有封装支付代码:直接上一段可用的流程代码吧:微信小程序支付官网文档有详细的说明,这里我就不再赘述啦:客户端js: wx.request({ url:'https://www.xxxx.c ...

  4. python基础学习(十二)变量进阶

    目录 1. 变量的引用 1.1 引用的概念 1.2 变量引用 的实例 1.3 函数的参数和返回值的传递 2. 可变和不可变类型 哈希 (hash) 3. 局部变量和全局变量 3.1 局部变量 3.2 ...

  5. Tri Tiling(hdu1143)

    Tri Tiling Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  6. JVM 垃圾回收机制

    首先JVM的内存结构包括五大区域: 程序计数器.虚拟机栈.本地方法栈.方法区.堆区.其中程序计数器.虚拟机栈和本地方法栈3个区域随线程启动与销毁, 因此这几个区域的内存分配和回收都具有确定性,不需要过 ...

  7. 洛谷P1792 [国家集训队]种树(链表 贪心)

    题意 题目链接 Sol 最直观的做法是wqs二分+dp.然而还有一种神仙贪心做法. 不难想到我们可以按权值从大到小依次贪心,把左右两边的打上标记,但这显然是错的比如\(1\ 231\ 233\ 232 ...

  8. [DOM基础]offsetHeight,clientHeight,scrollHeight,innerHeight,outerHeight等属性的解释

    由于经常搞混这几个属性,所以查找资料总结一下,方便以后翻出来温习. 一.偏移量-以offset开头的 1.offsetHeight:元素在垂直方向上占用的空间大小,像素.包括元素的高度.可见的水平滚动 ...

  9. 一个简单的scrollTop动画的方法

    var autoScrollTop = function (param) { var delay = param.scrollDom.height() * 20; param.dom.animate( ...

  10. java基础(五) String性质深入解析

    引言   本文将讲解String的几个性质. 一.String的不可变性   对于初学者来说,很容易误认为String对象是可以改变的,特别是+链接时,对象似乎真的改变了.然而,String对象一经创 ...