2 10 3 1 1 2 50 60 90 1 1 0 1 0 1 2 20 4 1 1 1 1 50 50 50 40 1 1 1 0 0 0 0 1 0 0 0
2.757813 0.000000
解题思路:有m门课,n天,每天可以复习特定的几门课,每门课有学分,基础分,复习一次可以加分,绩点有计算公式,问你总绩点最多多少?
解题代码:用最大费用流可以做。
#include <iostream> #include <cstdio> #include <queue> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; const int maxn=11000; const int maxm=1100000; const double inf=1e8; struct edge{ int u,v,next,f; double c; edge(int u0=0,int v0=0,int f0=0,double c0=0,int next0=0){ u=u0,v=v0,f=f0,c=c0,next=next0; } }e[maxm]; int head[maxn],path[maxn]; double dist[maxn]; bool visited[maxn]; int cnt,src,sink; void init(){ cnt=0; memset(head,-1,sizeof(head)); } void adde(int u,int v,int f,double c){ e[cnt].u=u,e[cnt].v=v,e[cnt].f=f,e[cnt].c=c,e[cnt].next=head[u],head[u]=cnt++; e[cnt].u=v,e[cnt].v=u,e[cnt].f=0,e[cnt].c=-c,e[cnt].next=head[v],head[v]=cnt++; } bool bfs(){ for(int i=src;i<=sink;i++){ dist[i]=-inf; path[i]=-1; } dist[src]=0; queue <int> q; q.push(src); visited[src]=true; while(!q.empty()){ int s=q.front(); q.pop(); for(int i=head[s];i!=-1;i=e[i].next){ int d=e[i].v; if(e[i].f>0 && dist[s]+e[i].c>dist[d]){ dist[d]=dist[s]+e[i].c; path[d]=i; if(!visited[d]){ visited[d]=true; q.push(d); } } } visited[s]=false; } return path[sink]>=0; } double getMaxCost(){ //int maxflow=0; double ret=0; while(bfs()){ int delta=inf; for(int i=sink;i!=src;i=e[path[i]].u){ if( e[path[i]].f<delta ) delta=e[path[i]].f; } for(int i=sink;i!=src;i=e[path[i]].u){ e[path[i]].f-=delta; e[path[i]^1].f+=delta; } ret+=dist[sink]*delta; //maxflow+=delta; } //cout<<"maxflow:"<<maxflow<<endl; return ret; } int nd,nf,nc; int fen[50],base[50],flag[50][50]; const double eps=1e-6; void input(){ for(int i=0;i<nc;i++) scanf("%d",&fen[i]); for(int i=0;i<nc;i++) scanf("%d",&base[i]); for(int i=0;i<nd;i++){ for(int j=0;j<nc;j++){ scanf("%d",&flag[i][j]); } } } double getf(double x){ return 4-3*(100-x)*(100-x)/1600.0; } void build(){ init(); src=0,sink=nc+nd+1; for(int i=0;i<nc;i++){ if(base[i]<60){ adde(src,i+1,60-base[i],inf); for(int t=60;t<100;t++){ adde(src,i+1,1, ( getf(t+1)-getf(t) )*fen[i] ); } }else{ for(int t=base[i];t<100;t++){ adde(src,i+1,1, ( getf(t+1)-getf(t) )*fen[i] ); } } } for(int i=0;i<nd;i++){ for(int j=0;j<nc;j++){ if(flag[i][j]){ adde(j+1,nc+i+1,nf,0); } } } for(int i=0;i<nd;i++){ adde(i+1+nc,sink,nf,0); } } void solve(){ build(); double ans=getMaxCost(); for(int i=head[src];i!=-1;i=e[i].next){ if(e[i].f>0 && e[i].c>inf-eps){ printf("0.000000\n"); return; } } int sum=0; for(int i=0;i<nc;i++) sum+=fen[i]; for(int i=0;i<nc;i++){ if(base[i]<60){ ans-=inf*(60-base[i]); ans+=( getf(60)-getf(base[i]) )*fen[i]; } ans+=getf(base[i])*fen[i]; } printf("%.6lf\n",ans/sum); } int main(){ while(scanf("%d%d%d",&nd,&nf,&nc)!=EOF && (nd||nf||nc) ){ input(); solve(); } return 0; }
HDU 4406 GPA(网络流-最大费用流),布布扣,bubuko.com
原文:http://blog.csdn.net/a1061747415/article/details/38497927