【BZOJ3442】学习小组

Description

【背景】
坑校准备鼓励学生参加学习小组。
【描述】
共有n个学生,m个学习小组,每个学生有一定的喜好,只愿意参加其中的一些学习小组,但是校领导为学生考虑,规定一个学生最多参加k个学习小组。财务处的大叔就没那么好了,他想尽量多收钱,因为每个学生参加学习小组都要交一定的手续费,不同的学习小组有不同的手续费。然而,事与愿违,校领导又决定对学习小组组织者进行奖励,若有a个学生参加第i个学习小组,那么给这个学习小组组织者奖励Ci*a^2元。在参与学生(而不是每个学习小组的人数总和)尽量多的情况下,求财务处最少要支出多少钱(若为负数,则输出负数)(支出=总奖励费-总手续费)。

Input

输入有若干行,第一行有三个用空格隔开的正整数n、m、k。接下来的一行有m个正整数,表示每个Ci。第三行有m个正整数,表示参加每个学习小组需要交的手续费Fi。再接下来有一个n行m列的矩阵,表若第i行j列的数字是1,则表示第i个学生愿意参加第j个学习小组,若为0,则为不愿意。

Output

输出只有一个整数,为最小的支出。

Sample Input

3 3 1
1 2 3
3 2 1
111
111
111

Sample Output

-2

题解:最小支出->最小费用流

首先很容易想到下面的几条边

1.S->每个同学 容量k,费用0
2.每个同学->他想去的学习小组 容量1,费用-f[i]

下面的一条边需要想一想,由于对每个学习小组的奖励是Ci*a^2,我想:该不会是把一条边拆成n条边,第i条费用为Ci*(2*i-1)吧? 是。

3.每个学习小组 -> T n条边,第i条容量1,费用Ci*(2*i-1)

发现这样做很好地解决了平方的问题,但下一条边感觉不WA一次是想不出来的了

4.每个同学 -> T 容量k-1,费用0

因为每个同学没必要参加那么多学习小组。但是辣鸡样例的k就是1,所以很难想到这一点

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <queue>
  4. #include <iostream>
  5. using namespace std;
  6. int n,m,k,cnt,S,T,ans,minn;
  7. int to[300000],next[300000],cost[300000],flow[300000],head[1000],f[110];
  8. int dis[1000],pe[1000],pv[1000],inq[1000];
  9. char str[110];
  10. queue<int> q;
  11. int rd()
  12. {
  13. int ret=0; char gc=getchar();
  14. while(gc<'0'||gc>'9') gc=getchar();
  15. while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
  16. return ret;
  17. }
  18. void add(int a,int b,int c,int d)
  19. {
  20. to[cnt]=b,cost[cnt]=c,flow[cnt]=d,next[cnt]=head[a],head[a]=cnt++;
  21. to[cnt]=a,cost[cnt]=-c,flow[cnt]=0,next[cnt]=head[b],head[b]=cnt++;
  22. }
  23. int bfs()
  24. {
  25. memset(dis,0x3f,sizeof(dis));
  26. int i,u;
  27. dis[S]=0,q.push(S);
  28. while(!q.empty())
  29. {
  30. u=q.front(),q.pop(),inq[u]=0;
  31. for(i=head[u];i!=-1;i=next[i])
  32. {
  33. if(dis[to[i]]>dis[u]+cost[i]&&flow[i])
  34. {
  35. dis[to[i]]=dis[u]+cost[i],pe[to[i]]=i,pv[to[i]]=u;
  36. if(!inq[to[i]]) inq[to[i]]=1,q.push(to[i]);
  37. }
  38. }
  39. }
  40. return dis[T]<0x3f3f3f3f;
  41. }
  42. int main()
  43. {
  44. n=rd(),m=rd(),k=rd();
  45. int i,j,l,a;
  46. S=0,T=n+m+1;
  47. memset(head,-1,sizeof(head));
  48. for(i=1;i<=m;i++)
  49. {
  50. a=rd();
  51. for(j=1;j<=n;j++) add(n+i,T,(2*j-1)*a,1);
  52. }
  53. for(i=1;i<=m;i++) f[i]=rd();
  54. for(i=1;i<=n;i++)
  55. {
  56. scanf("%s",str);
  57. add(S,i,0,k),add(i,T,0,k-1);
  58. for(j=1;j<=m;j++) if(str[j-1]=='1') add(i,n+j,-f[j],1);
  59. }
  60. while(bfs())
  61. {
  62. minn=1<<30;
  63. for(i=T;i;i=pv[i]) minn=min(minn,flow[pe[i]]);
  64. ans+=minn*dis[T];
  65. for(i=T;i;i=pv[i]) flow[pe[i]]-=minn,flow[pe[i]^1]+=minn;
  66. }
  67. printf("%d",ans);
  68. return 0;
  69. }

【BZOJ3442】学习小组 费用流的更多相关文章

  1. bzoj3442学习小组

    bzoj3442学习小组 题意: 共有n个学生,m个学习小组,每个学生只愿意参加其中的一些学习小组,且一个学生最多参加k个学习小组.每个学生参加学习小组财务处都收一定的手续费,不同的学习小组有不同的手 ...

  2. bzoj3442: 学习小组(费用流好题)

    3442: 学习小组 题目:传送门 题解: 超级好题啊大佬们的神题!建图肥肠灵性!感觉自己是星际玩家... 首先呢st直接向每个人连边,容量为min(k,喜欢的小组个数),费用为0 然后每个人再向ed ...

  3. BZOJ3442: 学习小组

    Description [背景] 坑校准备鼓励学生参加学习小组. [描述]     共有n个学生,m个学习小组,每个学生有一定的喜好,只愿意参加其中的一些学习小组,但是校领导为学生考虑,规定一个学生最 ...

  4. 【BZOJ 3442】 3442: 学习小组 (最大费用流)

    3442: 学习小组 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 403  Solved: 193 Description [背景] 坑校准备鼓励学生 ...

  5. 学习了ZKW费用流

    所谓ZKW费用流,其实就是Dinic. 若干年前有一个人发明了最小增广路算法,每次用BFS找一条增广路,时间O(nm^2) 然后被DinicD飞了:我们为什么不可以在长度不变时多路增广呢?时间O(n^ ...

  6. zkw费用流 学习笔记

    分析 记\(D_i\)为从\(S\)出发到\(i\)的最短路 最短路算法保证, 算法结束时 对于任意存在弧\((i,j)\)满足\(D_i + c_{ij}\ge D_j\) ① 且对于每个 \(j\ ...

  7. 【BZOJ】【3442】学习小组

    网络流/费用流 orz zyf 裸的费用流,根据题目描述即可建出如下的图: S->i 费用表示每有一个加入第 i 个小组的学生,需要花的钱,由于是跟流量(人数)的二次方相关,所以要拆边……然后每 ...

  8. 【刷题】洛谷 P4209 学习小组

    题目描述 共有n个学生,m个学习小组,每个学生只愿意参加其中的一些学习小组,且一个学生最多参加k个学习小组.每个学生参加学习小组财务处都收一定的手续费,不同的学习小组有不同的手续费.若有a个学生参加第 ...

  9. BZOJ3130: [Sdoi2013]费用流[最大流 实数二分]

    3130: [Sdoi2013]费用流 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 960  Solved: 5 ...

随机推荐

  1. firefox浏览器批处理插件imacros

    http://www.360doc.com/content/14/1012/19/4360822_416372016.shtml javascript部分 var code = "CODE: ...

  2. RVM(ruby version manage)安装指南

    一.安装需要3步gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 \c ...

  3. Cadence技巧01:利用Excel速新建原理图元件库

    Cadence技巧01:利用Excel速新建原理图元件库 听语音 | 浏览:1698 | 更新:2015-07-02 09:41 | 标签:excel 1 2 3 4 5 6 7 分步阅读 一键约师傅 ...

  4. Activity生命运行中的几个方法

    给大家看看一个周期图

  5. ENGINE_API CXSroll

    #ifndef __XSROLL_H__ #define __XSROLL_H__ #include "CocoHead.h" #include "XWindow.h&q ...

  6. jquery 获取字符串中的数字

    str_num = 'abc123' num = parseInt(str_num.replace(/[^0-9]/ig,"")); alert(num);

  7. linux查看匹配内容的前后几行(转)

    linux系统中,利用grep打印匹配的上下几行   如果在只是想匹配模式的上下几行,grep可以实现.   $grep -5 'parttern' inputfile //打印匹配行的前后5行   ...

  8. 华中农业大学校赛--c The Same Color

    Problem C: The Same Color Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 993  Solved: 595[Submit][St ...

  9. Unity3D学习(九):C#和C++的相互调用

    前言 不知不觉已经一年了,这一年来一直忙于公司项目疯狂加班,很少有自己的时间写下东西.不过好在项目最近也步入正轨了,正好抽空写点东西记录下学到的一些东西. 公司项目是一个端游IP移植手游,端游是基于C ...

  10. PHP flock() 函数 php中的文件锁定机制

    举一个例子: 假设一个文件读取的过程,有数万人在同时操作,那么极可能a用户刚刚写入,b用户也写入了,两者以至于混乱,或者在读取的时候,读取到别人写的数据.就好比上公共厕所,去厕所的时候要把门给打开上, ...