HDU 4406
来源:互联网 发布:矩阵潜袭有手机 编辑:程序博客网 时间:2024/06/09 16:26
费用流
建图还是比较简单的。。。(参见下面代码)
#include<cstdio>#include<cstring>#include<queue>#define N 100#define inf 100000000using namespace std;int cre[N],tot_cre;int sco[N];int head[N],cnt,dis[N],pre[N],vis[N],ans[N];int n;struct Edge{ int u,v,c,w,next;}edge[80010];void addedge(int u,int v,int cap,int cost){ edge[cnt].u=u; edge[cnt].v=v; edge[cnt].c=cap; edge[cnt].w=cost; edge[cnt].next=head[u]; head[u]=cnt++; edge[cnt].u=v; edge[cnt].v=u; edge[cnt].c=0; edge[cnt].w=-cost; edge[cnt].next=head[v]; head[v]=cnt++;}bool spfa(){ int i,j; queue<int>q; q.push(0); for(i=1;i<=n;i++) dis[i]=-inf,vis[i]=0; dis[i]=0,vis[0]=1; while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=0; for(i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(edge[i].c && dis[v] < dis[u]+edge[i].w){ dis[v]=dis[u]+edge[i].w; pre[v]=i; if(!vis[v]){ vis[v]=1; q.push(v); } } } } if(dis[n]==-inf)return 0; return 1;}void end(){ int u,p,cap=-1; for(u=n;u;u=edge[p].u){ p=pre[u]; if(cap==-1 || cap>edge[p].c) cap=edge[p].c; } for(u=n;u;u=edge[p].u){ p=pre[u]; edge[p].c-=cap; edge[p^1].c+=cap; }}void init(){ memset(head,-1,sizeof(head)); memset(ans,0,sizeof(ans)); cnt=tot_cre=0;}int main(){ int i,j; int v,e,k; int pre,now,tem; while(scanf("%d %d %d",&v,&k,&e)){ if(v==0 && k==0 && e==0)break; init(); for(i=1;i<=e;i++){ scanf("%d",&cre[i]); tot_cre+=cre[i]; } n=v+e+1; for(i=1;i<=v;i++) addedge(0,i,k,0); for(i=1;i<=e;i++){ scanf("%d",&sco[i]); if(sco[i]<60){ pre=6400-3*(100-60)*(100-60); addedge(i+v,n,60-sco[i],inf); for(j=61;j<=100;j++){ now=6400-3*(100-j)*(100-j); addedge(i+v,n,1,(now-pre)*cre[i]); pre=now; } } else{ pre=6400-3*(100-sco[i])*(100-sco[i]); for(j=sco[i]+1;j<=100;j++){ now=6400-3*(100-j)*(100-j); addedge(i+v,n,1,(now-pre)*cre[i]); pre=now; } } } for(i=1;i<=v;i++) for(j=1;j<=e;j++){ scanf("%d",&tem); if(tem) addedge(i,v+j,k,0); } while(spfa()) end(); for(i=head[n];i!=-1;i=edge[i].next) ans[edge[i].v-v]+=edge[i].c; bool flag=1; int sum=0; for(i=1;i<=e;i++){ if(ans[i]+sco[i]<60){ flag=0; break; } sum+=(6400-3*(100-ans[i]-sco[i])*(100-ans[i]-sco[i]))*cre[i]; } if(!flag)printf("0.000000\n"); else printf("%.6lf\n",(double)sum/tot_cre/1600); }}
如果边权用的是double类型的话一定记得加上eps
见下面代码(注意加上//////的代码)
#include<cstdio>#include<cstring>#include<queue>#include<cmath>#define N 100#define inf 100000000using namespace std;int cre[N],tot_cre;int sco[N];int head[N],cnt,pre[N],vis[N],ans[N];double dis[N];int n;struct Edge{ int u,v,c,next; double w;}edge[80010];void addedge(int u,int v,int cap,double cost){ edge[cnt].u=u; edge[cnt].v=v; edge[cnt].c=cap; edge[cnt].w=cost; edge[cnt].next=head[u]; head[u]=cnt++; edge[cnt].u=v; edge[cnt].v=u; edge[cnt].c=0; edge[cnt].w=-cost; edge[cnt].next=head[v]; head[v]=cnt++;}bool spfa(){ int i,j; queue<int>q; q.push(0); for(i=1;i<=n;i++) dis[i]=-inf,vis[i]=0; dis[i]=0,vis[0]=1; while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=0; for(i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(edge[i].c && dis[v]-dis[u]-edge[i].w<-1e-9){ ///// dis[v]=dis[u]+edge[i].w; pre[v]=i; if(!vis[v]){ vis[v]=1; q.push(v); } } } } if(fabs(dis[n]+inf)<1e-9)return 0; ///// return 1;}void end(){ int u,p,cap=-1; for(u=n;u;u=edge[p].u){ p=pre[u]; if(cap==-1 || cap>edge[p].c) cap=edge[p].c; } for(u=n;u;u=edge[p].u){ p=pre[u]; edge[p].c-=cap; edge[p^1].c+=cap; }}void init(){ memset(head,-1,sizeof(head)); memset(ans,0,sizeof(ans)); cnt=tot_cre=0;}int main(){ int i,j; int v,e,k; int pre,now,tem; while(scanf("%d %d %d",&v,&k,&e)){ if(v==0 && k==0 && e==0)break; init(); for(i=1;i<=e;i++){ scanf("%d",&cre[i]); tot_cre+=cre[i]; } n=v+e+1; for(i=1;i<=v;i++) addedge(0,i,k,0); for(i=1;i<=e;i++){ scanf("%d",&sco[i]); if(sco[i]<60){ pre=6400-3*(100-60)*(100-60); addedge(i+v,n,60-sco[i],inf); for(j=61;j<=100;j++){ now=6400-3*(100-j)*(100-j); addedge(i+v,n,1,((double)now-pre)*cre[i]/(tot_cre*1600)); pre=now; } } else{ pre=6400-3*(100-sco[i])*(100-sco[i]); for(j=sco[i]+1;j<=100;j++){ now=6400-3*(100-j)*(100-j); addedge(i+v,n,1,((double)now-pre)*cre[i]/(tot_cre*1600)); pre=now; } } } for(i=1;i<=v;i++) for(j=1;j<=e;j++){ scanf("%d",&tem); if(tem) addedge(i,v+j,k,0); } while(spfa()) end(); for(i=head[n];i!=-1;i=edge[i].next) ans[edge[i].v-v]+=edge[i].c; bool flag=1; double sum=0; for(i=1;i<=e;i++){ if(ans[i]+sco[i]<60){ flag=0; break; } sum+=((double)6400-(double)3*(100-ans[i]-sco[i])*(100-ans[i]-sco[i]))*cre[i]/(tot_cre*1600); } if(!flag)printf("0.000000\n"); else printf("%.6lf\n",sum); }}
- HDU 4406
- HDU 4406
- hdu 4406
- hdu 4406 费用流
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- mac php 配置
- C#自定义事件的步骤
- CentOS在VirtualBox下安装没有图形界面的解决方法
- C语言字符串长度
- Agile PLM: Agile PLM 9.3.1.2主程序升级失败的一个案例
- HDU 4406
- 如何设置Office2010直接打开.doc文件
- 线段树~总结下吧
- 二次筛法
- C#.net串口通信详解!
- 大数类java.math.BigInteger
- Scilab 画圆的渐伸线
- 优秀有价值的博客收藏列表(持续更新)
- android对话框介绍2 自定义对话框