[BZOJ2245][SDOI2011]工作安排(费用流)
2016-05-10 11:00
344 查看
题目描述
传送门题解
对于每个产品,s->i,Ci,INF对于员工j可以生产产品i,i->j,INF,Ci
对于每一个员工i以及枚举到的si=j,i->t,T[i][j]-T[i][j-1],W[i][j]
代码
#include<iostream> #include<cstring> #include<cstdio> #include<queue> using namespace std; #define LL long long const int max_n=300; const int max_N=max_n*10+2; const int max_m=max_N*100; const int max_e=max_m*2; const LL INF=1e18; LL m,n,sum,N,mincost; LL A[max_n][max_n],s[max_n],ss[max_n],C[max_n],T[max_n][max_n],W[max_n][max_n]; LL tot,point[max_N],nxt[max_e],v[max_e],remain[max_e],c[max_e]; LL dis[max_N],last[max_N]; bool vis[max_N]; queue <LL> q; inline void addedge(LL x,LL y,LL cap,LL z) { ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; remain[tot]=cap; c[tot]=z; ++tot; nxt[tot]=point[y]; point[y]=tot; v[tot]=x; remain[tot]=0; c[tot]=-z; } inline LL addflow(LL s,LL t) { LL now=t,ans=INF; while (now!=s) { ans=min(ans,remain[last[now]]); now=v[last[now]^1]; } now=t; while (now!=s) { remain[last[now]]-=ans; remain[last[now]^1]+=ans; now=v[last[now]^1]; } return ans; } inline bool bfs(LL s,LL t) { for (LL i=1;i<=N;++i) dis[i]=INF; dis[s]=0; memset(vis,0,sizeof(vis)); vis[s]=true; while (!q.empty()) q.pop(); q.push(s); while (!q.empty()) { LL now=q.front(); q.pop(); vis[now]=false; for (LL i=point[now];i!=-1;i=nxt[i]) if (dis[v[i]]>dis[now]+c[i]&&remain[i]) { dis[v[i]]=dis[now]+c[i]; last[v[i]]=i; if (!vis[v[i]]) { vis[v[i]]=true; q.push(v[i]); } } } if (dis[t]==INF) return false; LL flow=addflow(s,t); mincost+=flow*dis[t]; return true; } inline void mincost_flow(LL s,LL t) { while (bfs(s,t)); } int main() { tot=-1; memset(point,-1,sizeof(point)); memset(nxt,-1,sizeof(nxt)); scanf("%lld%lld",&m,&n); for (LL i=1;i<=n;++i) scanf("%lld",&C[i]); for (LL i=1;i<=m;++i) for (LL j=1;j<=n;++j) scanf("%lld",&A[i][j]); for (LL i=1;i<=m;++i) { scanf("%lld",&s[i]); for (LL j=1;j<=s[i];++j) scanf("%lld",&T[i][j]); T[i][s[i]+1]=INF; for (LL j=1;j<=s[i]+1;++j) scanf("%lld",&W[i][j]); } N=n+m+2; for (LL i=1;i<=n;++i) addedge(1,1+i,C[i],0); for (LL i=1;i<=n;++i) for (LL j=1;j<=m;++j) if (A[j][i]) addedge(1+i,1+n+j,INF,0); for (LL i=1;i<=m;++i) for (LL j=1;j<=s[i]+1;++j) addedge(1+n+i,N,T[i][j]-T[i][j-1],W[i][j]); mincost_flow(1,N); printf("%lld\n",mincost); }
总结
刚开始读错题了233相关文章推荐
- android 使用Http的Get方式读取网络数据
- 理解力
- Android事件分发机制(一) Touch 事件的分发和消费机制
- Elasticsearch源码分析二--调用Lucene查询接口之常用词查询
- iOS - 静态与动态内存分析
- Firebug入门指南
- hadoop2.6在window上搭建测试环境
- tcp 短连接 优化
- 注册验证码业务
- java学习
- js中易混淆的方法及概念
- UVA 10600 ACM Contest and Blackout 次小生成树
- shell教程-001:shell简介 什么是shell,shell命令的两种执行方式
- Oracle、MySQL和SqlServe分页查询的语句区别
- Linux rm & cp
- [Vue warn]: Attribute "id" is ignored on component <div> because the component is a fragment instan
- 强大的测试管理工具---TestTrack Pro
- mysql密码正确但无法登陆
- 程序员必须知道的几个Git代码托管平台
- Android判断网络连接