题意:现有m门课程需要复习,已知每门课程的基础分和学分,共有n天可以复习,每天分为k个时间段,每个时间段可以复习一门课程,并使这门课程的分数加一,问在不挂科的情况下最高的绩点。

思路:(没做过费用流的转这里:http://www.cnblogs.com/L-King/p/5316359.html),首先我们得保证每门课程都达到60分,所以对每一门未到60分的课程添加一条从S(即源点)出发的弧,容量为60-该课程的分数,花费为INF,因此在执行费用流的时候会优先增广此弧。此时,我们已经保证了在条件允许的情况下,每门课程都达到60分以上。接下来就是剩下的分数的分配,设f(x)为x对应的p;可解得f(x)以及f'(x)都是减函数(x>=60),即f(x+1)-f(x)<f(x)-f(x-1),因此可以对每一分连接一条容量为1,费用为f(x)-f(x-1)的弧。最后就是每门课程与对应的天连接一条容量为k,费用为0的弧,每一天与T(即汇点)连接一条容量为k,费用为0的弧。最后跑一下费用流,然后判断是否有课程未达到60分。

代码:

#include<stdio.h>
#include<string.h>
#define min(x,y) (x)<(y)?(x):(y) const int N=,M=,INF=0x3f3f3f3f;
struct node
{
int u,v,c,next;
double w;
}e[M];
int head[N],q[M],p[N],pre[N];
int s,t,l,r,cnt;
double d[N];
int w[N],b[N],f[N];
void add(int u,int v,int c,double w)
{
e[cnt].u=u,e[cnt].v=v,e[cnt].c=c,e[cnt].w=w;
e[cnt].next=head[u],head[u]=cnt++;
e[cnt].u=v,e[cnt].v=u,e[cnt].c=,e[cnt].w=-w;
e[cnt].next=head[v],head[v]=cnt++;
}
void init()
{
memset(head,-,sizeof(head));
cnt=;
} int spfa()
{
int i,u,v;
double w;
memset(pre,-,sizeof(pre));
memset(p,,sizeof(p));
memset(f,,sizeof(f));
for(i=;i<=t;i++) d[i]=-1.0*INF;
l=r=;d[s]=;f[s]=INF;q[++r]=s;
while(l<r)
{
p[u=q[++l]]=;
for(i=head[u];i!=-;i=e[i].next)
{
v=e[i].v,w=e[i].w;
if(e[i].c&&d[v]<d[u]+w)
{
d[v]=d[u]+w;
f[v]=min(f[u],e[i].c);
pre[v]=i;
if(!p[v])
{
q[++r]=v;
p[v]=;
}
}
}
}
return f[t];
} double getp(int x,int w)
{
return (4.0-3.0*(-x)*(-x)/)*w;
}
void MicMaf()
{
int m;
while(m=spfa())
{
for(int i=pre[t];i!=-;i=pre[e[i].u])
{
e[i].c-=m;
e[i^].c+=m;
}
}
}
int main()
{
int n,m,k,i,j,x;
while(scanf("%d%d%d",&n,&k,&m),n||m||k)
{
init();s=,t=n+m+;
for(i=;i<=m;i++) scanf("%d",&w[i]);
for(i=;i<=m;i++) scanf("%d",&b[i]);
for(i=;i<=n;i++)
{
add(i+m,t,k,);
for(j=;j<=m;j++)
{
scanf("%d",&x);
if(x) add(j,i+m,k,);
}
}
double pre,cur;
for(i=;i<=m;i++)
{
if(b[i]<)
{
add(s,i,-b[i],1.0*INF);
pre=getp(,w[i]);
for(j=;j<=;j++)
{
cur=getp(j,w[i]);
add(s,i,,cur-pre);
pre=cur;
}
}
else
{
pre=getp(b[i],w[i]);
for(j=b[i]+;j<=;j++)
{
cur=getp(j,w[i]);
add(s,i,,cur-pre);
pre=cur;
}
}
}
MicMaf();
for(i=head[s];i!=-;i=e[i].next)
b[e[i].v]+=e[i^].c;
int sum=;double ans=;
for(i=;i<=m;i++)
sum+=w[i];
for(i=;i<=m;i++)
{
if(b[i]<) break;
ans+=getp(b[i],w[i])/sum;
}
if(i<=m) ans=;
printf("%.6f\n",ans);
}
return ;
}

参考文章:http://www.cnblogs.com/jianglangcaijin/archive/2012/10/06/2713375.html

     http://www.xuebuyuan.com/2064806.html

HDU 4406 最大费用最大流的更多相关文章

  1. hdu 4322(最大费用最大流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4322 思路:建图真的是太巧妙了!直接copy大牛的了: 由于只要得到糖就肯定有1个快乐度,在这一点上糖 ...

  2. 【网络流#2】hdu 1533 - 最小费用最大流模板题

    最小费用最大流,即MCMF(Minimum Cost Maximum Flow)问题 嗯~第一次写费用流题... 这道就是费用流的模板题,找不到更裸的题了 建图:每个m(Man)作为源点,每个H(Ho ...

  3. hdu 1533(最小费用最大流)

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  4. hdu 4862KM&最小费用最大流

    /*最小K路径覆盖的模型,用费用流或者KM算法解决, 构造二部图,X部有N*M个节点,源点向X部每个节点连一条边, 流量1,费用0,Y部有N*M个节点,每个节点向汇点连一条边,流量1, 费用0,如果X ...

  5. HDU 4322Candy 最大费用最大流

    由于被小孩子不喜欢的糖果的对小孩产生的效力是一样的,所以我们在网络流的时候先不考虑. 1 - 源点0到1~N个糖果,容量为1,费用为02 - 根据like数组,like[i][j] == 1时在糖果j ...

  6. hdu 4067(最小费用最大流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4067 思路:很神奇的建图,参考大牛的: 如果人为添加t->s的边,那么图中所有顶点要满足的条件都 ...

  7. HDU 1533 最小费用最大流(模板)

    http://acm.hdu.edu.cn/showproblem.php?pid=1533 这道题直接用了模板 题意:要构建一个二分图,家对应人,连线的权值就是最短距离,求最小费用 要注意void ...

  8. hdu 3667(最小费用最大流+拆边)

    Transportation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  9. hdu 2485(最小费用最大流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2485 思路:题目的意思是删除最少的点使1,n的最短路大于k.将点转化为边,容量为1,费用为0,然后就是 ...

随机推荐

  1. 【Asphyre引擎】学习笔记(一)

    先来说说一下几个最基本的对象: TGraphicsDeviceProvider:这个对象决定我们的游戏是用什么来渲染的,比如DX或者OpenGL,DX还有多个版本可以选择. TCustomSwapCh ...

  2. 【Asphyre引擎】Asphyre时隔3年,更名为PXL,全平台支持!

    ps:回忆日志 新版本10月初就推出了,我第一时间(10.2日更新,我当天就看到了)下载下来.发现部分Demo需要XE8才能编译通过,又去下载了一个XE8.折腾完已经深夜,只是粗粗的把Demo都编译了 ...

  3. Visual Studio 2013 Preview 新功能

    先来看一下Visual Studio的版本历史: 1. Visual Studio.NET 2002 2. Visual Studio.NET 2003 3. Visual Studio.NET 20 ...

  4. SQL学习笔记:选取第N条记录

    Northwind数据库,选取价格第二高的产品. 有两种方法,一个是用Row_Number()函数: SELECT productname FROM ( productname, Row_Number ...

  5. mysql innoDB 挂了的临时解决方案

    Mysql InnoDB: Error: checksum mismatch by Mattias Hemmingsson on December 23, 2013 in Linux • 6 Comm ...

  6. java多线程系列8-线程的优先级

    在java中设置线程优先级使用setPriority,在jdk中的源代码如下: public final void setPriority(int newPriority) { ThreadGroup ...

  7. 【转】Windows的多线程编程,C/C++

    在Windows的多线程编程中,创建线程的函数主要有CreateThread和_beginthread(及_beginthreadex). CreateThread 和 ExitThread    使 ...

  8. 深入理解java虚拟机(1)------内存区域与内存溢出

    在C++领域,关于C++的内存存储,结构等等,有一本书:深度探索C++对象模型,讲解的非常透彻. 而Java确把这一工作交给了虚拟机来处理. 我们首先来看看关于内存的问题. 1.问题: 1)java ...

  9. Mysql中的函数

    什么是函数 mysql中的函数与存储过程类似,都是一组SQL集: 与存储过程的区别 函数可以return值,存储过程不能直接return,但是有输出参数可以输出多个返回值: 函数可以嵌入到sql语句中 ...

  10. 【转载】改善数据质量从数据剖析(Data Profiling)开始

    市场研究公司Forrester副总裁Erin Kinikin曾经把低劣的数据质量做了一个形象的比喻“用更好的方法访问劣质的数据,结果类似于把已经腐烂了的桃子用更快的卡车,走更好的路线运输到达市场时,桃 ...