【BZOJ】【3442】学习小组

网络流/费用流



  orz zyf

  裸的费用流,根据题目描述即可建出如下的图:

  S->i 费用表示每有一个加入第 i 个小组的学生,需要花的钱,由于是跟流量(人数)的二次方相关,所以要拆边……然后每个人的报名费直接用支出减去即可(也就是每条边的费用都减去一个常量)

  i->j+m 根据矩阵连边……如果第 j 个学生能报名第 i 个小组即连一条边,费用为0。

  j+m->T 容量为k,费用为0,表示每个人最多报k个小组。

  但是这题很坑啊!限制条件是参与学生尽量多,也就是说在一定会亏的时候每人最多只报一个小组……刚刚的建图,最小费用最大流行不通了!

  我们想想,如果一个人报名了会使得总支出减少,那他肯定要报名某一个小组,如果不能减少的话……就让这个改变量为0好了!

  所以我们对于每个人 j ,连边S->j+m (k-1,0)表示这个人最多可以有k-1个报名机会直接放弃掉!(因为要让参与人数尽量多啊……所以不能是k)

  1 /**************************************************************
  2     Problem: 3442
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:1560 ms
  7     Memory:3624 kb
  8 ****************************************************************/
  9
 10 //BZOJ 3442
 11 #include<vector>
 12 #include<cstdio>
 13 #include<cstring>
 14 #include<cstdlib>
 15 #include<iostream>
 16 #include<algorithm>
 17 #define rep(i,n) for(int i=0;i<n;++i)
 18 #define F(i,j,n) for(int i=j;i<=n;++i)
 19 #define D(i,j,n) for(int i=j;i>=n;--i)
 20 #define pb push_back
 21 using namespace std;
 22 inline int getint(){
 23     int v=0,sign=1; char ch=getchar();
 24     while(ch<‘0‘||ch>‘9‘){ if (ch==‘-‘) sign=-1; ch=getchar();}
 25     while(ch>=‘0‘&&ch<=‘9‘){ v=v*10+ch-‘0‘; ch=getchar();}
 26     return v*sign;
 27 }
 28 const int N=410,M=100000,INF=~0u>>2;
 29 typedef long long LL;
 30 /******************tamplate*********************/
 31 int n,m,k,ans,tmp,num,c[N];
 32 struct edge{int from,to,v,c;};
 33 struct Net{
 34     edge E[M];
 35     int head[N],next[M],cnt;
 36     void ins(int x,int y,int z,int c){
 37         E[++cnt]=(edge){x,y,z,c};
 38         next[cnt]=head[x]; head[x]=cnt;
 39     }
 40     void add(int x,int y,int z,int c){
 41         ins(x,y,z,c); ins(y,x,0,-c);
 42     }
 43     int from[N],Q[M],d[N],S,T,ed;
 44     bool inq[N],sign;
 45     bool spfa(){
 46         int l=0,r=-1;
 47         F(i,1,T) d[i]=INF;
 48         d[S]=0; Q[++r]=S; inq[S]=1;
 49         while(l<=r){
 50             int x=Q[l++];
 51             inq[x]=0;
 52             for(int i=head[x];i;i=next[i])
 53                 if(E[i].v>0 && d[x]+E[i].c<d[E[i].to]){
 54                     d[E[i].to]=d[x]+E[i].c;
 55                     from[E[i].to]=i;
 56                     if (!inq[E[i].to]){
 57                         Q[++r]=E[i].to;
 58                         inq[E[i].to]=1;
 59                     }
 60                 }
 61         }
 62         return d[T]!=INF;
 63     }
 64     void mcf(){
 65         int x=INF;
 66         for(int i=from[T];i;i=from[E[i].from])
 67             x=min(x,E[i].v);
 68         for(int i=from[T];i;i=from[E[i].from]){
 69             E[i].v-=x;
 70             E[i^1].v+=x;
 71         }
 72         ans+=x*d[T];
 73     }
 74     void init(){
 75         n=getint(); m=getint(); k=getint(); cnt=1;
 76         S=0; T=n+m+1; num=sign=0; tmp=-INF;
 77         F(i,1,m) c[i]=getint();
 78         int x;
 79         F(i,1,m){
 80             x=getint();
 81             F(j,1,n) add(S,i,1,c[i]*(j*2-1)-x);
 82         }
 83         char s[120];
 84         F(i,1,n) {
 85             scanf("%s",s+1);
 86             F(j,1,m){
 87                 x=s[j]-‘0‘;
 88                 if (x) add(j,i+m,1,0);
 89             }
 90         }
 91         F(i,1,n) add(S,i+m,k-1,0),add(i+m,T,k,0);
 92         while(spfa()) mcf();
 93         printf("%d\n",ans);
 94     }
 95 }G1;
 96
 97 int main(){
 98 #ifndef ONLINE_JUDGE
 99     freopen("3442.in","r",stdin);
100     freopen("3442.out","w",stdout);
101 #endif
102     G1.init();
103     return 0;
104 }

时间: 2024-10-13 09:36:57

【BZOJ】【3442】学习小组的相关文章

BZOJ 3442 学习小组 费用流

题目大意:给出学生的数目和学习小组的数目,学生参加小组需要交纳费用,每个小组会支出C[i]*cnt[i]^2.每个学生可以参加k个小组,问最多的学生参加时,最小支出费用. 思路:如果不算后面那个什么鬼的条件的话,见图十分显然. S->每个学生 f:k,c:0 每个学生->每个学习小组 f:1,c:-F[i] 每个学习小组->T f:1,c:1 * C[i],3 * C[i],5 * C[i],7 * C[i],...... 后面的条件其实是说,每个学生的k次机会不一定全用光,但是所有人都

bzoj3442 学习小组

目前处于迷之TLE状态 3442: 学习小组 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 200  Solved: 87 Description [背景] 坑校准备鼓励学生参加学习小组. [描述] 共有n个学生,m个学习小组,每个学生有一定的喜好,只愿意参加其中的一些学习小组,但是校领导为学生考虑,规定一个学生最多参加k个学习小组.财务处的大叔就没那么好了,他想尽量多收钱,因为每个学生参加学习小组都要交一定的手续费,不同的学习小组有不同的手续费.

怎样增加Dave 英语学习小组

一.     增加小组 英语对IT 是非常重要的,但非常多人都不能坚持去学习,Dave 英语学习小组成立与已经超过半年,如今进行扩招.欢迎想提高英语,而且能够坚持每天学习的人,增加Dave 的小组.并坚持每天学习. 要求: (1)  从增加小组当天開始,计算打卡率. (2)   打卡率低于85%的,会被剔出小组,须要又一次增加. (3)  能够安装手机client.利用上下班的零碎时间来学习. (4)  每天学习英语时间控制在1小时左右. 注冊扇贝帐号: http://www.shanbay.c

【原创】如何组织好一个学习小组

如何组织好一个学习小组 引言 学习小组做的很多,成功的很少,如何做好一个学习小组,需要投入很多心思,比如选择学习内容,是否是大家感兴趣的:大家的时间问题:如何能保证大家学有所成-.但我们还是做了,这里给您展示我们学习小组的进展情况. 背景 学习小组从上周成立(和党的生日一天吧),本期学习内容是<C#图解教程>,学习的主力是4个实习生,及公司的测试经理(因测试经理没有开发经验,所以从基础做起吧),测试经理担任学习小组的组长.由于考虑到比较基础,每个人分2-3章,所以总计分配了10章内容.并让大家

【bzoj3442】学习小组 费用流

原文地址:http://www.cnblogs.com/GXZlegend/p/6809670.html 题目描述 [背景] 坑校准备鼓励学生参加学习小组. [描述] 共有n个学生,m个学习小组,每个学生有一定的喜好,只愿意参加其中的一些学习小组,但是校领导为学生考虑,规定一个学生最多参加k个学习小组.财务处的大叔就没那么好了,他想尽量多收钱,因为每个学生参加学习小组都要交一定的手续费,不同的学习小组有不同的手续费.然而,事与愿违,校领导又决定对学习小组组织者进行奖励,若有a个学生参加第i个学习

Django学习小组出品:一起来做一个简单的Blog第一周文档(教程)

本节是 django blog 项目的开篇,是 django 学习小组的集体学习成果.django学习小组是由我发起的一个促进 django 新手互相学习.互相帮助的组织.小组在一边学习 django 的同时将一起完成三个项目: 一个简单django blog,用于发布小组每周的学习和开发文档 django中国社区,为国内的 django 开发者们提供一个长期维护的 django 社区,聚集全国的 django 开发者到这个社区上来 django 问答社区, 类似于segmentfault 和

bzoj3442学习小组

题意: 共有n个学生,m个学习小组,每个学生只愿意参加其中的一些学习小组,且一个学生最多参加k个学习小组.每个学生参加学习小组财务处都收一定的手续费,不同的学习小组有不同的手续费.若有a个学生参加第i个学习小组,财务处支付奖励Ci*a^2元.在参与学生(而不是每个学习小组的人数总和)尽量多的情况下,求财务处最少要支出多少钱. 题解: s连n个学生,流量为k,费用为0.每个学生向喜欢的小组的连边,流量为1,费用为手续费的相反数.每个小组向t连边,它的费用与流量的平方成正比的边,需要把它拆成k条流量

20175212童皓桢 学习小组结对声明

20175212童皓桢 学习小组结对声明 小组成员 20175212 童皓桢 20175227 张雪莹 小组合照 感想 结对编程并不适用众所周知的短板效应,而是相反的,程序的质量取决于水平较高的那一方,因此结对益处极大.再者,无论是什么科目,什么方向的学习,正所谓男女搭配,干活不累,抱团取暖,学到天黑,良好的搭档能够提供的不仅仅是表面上的督促或者讨论,更甚带来的是一种氛围,一种习惯,一种可能贯穿你一生的思路和思考方法.短期目标通过结对学习,(对Java的学习理解提高到一个新的层次! 原文地址:h

结对学习小组

结对学习小组 小组成员 结对同学20175212童皓桢 本人学号20175227张雪莹 小组合照 感想 结对学习是为了达到更好的学习效果,在学习过程中,互帮互助,互相发现逻辑上的错误,讨论纠正后提高思考问题.发表观点.讨论磨合的能力:我们一个踏实,一个思维活跃,相信在以后的Java学习过程中,能学得更好 原文地址:https://www.cnblogs.com/zxy20175227/p/10590337.html