【LuoguP3410】拍照
2018-02-14 22:26
134 查看
题目链接
有m个人,每个人都愿意付给小B一定钱让n个人中的一些人进行合影。如果这一些人没带齐那么就不能拍照,小B也不会得到钱。
注意:带下属不是白带的!!!对于每个下属,如果他带了那么小B需要给他一些钱,保证当他拍照时配合。
请问,小B的净收益最多是多少。
题目描述
小B有n个下属,现小B要带着一些下属让别人拍照。有m个人,每个人都愿意付给小B一定钱让n个人中的一些人进行合影。如果这一些人没带齐那么就不能拍照,小B也不会得到钱。
注意:带下属不是白带的!!!对于每个下属,如果他带了那么小B需要给他一些钱,保证当他拍照时配合。
请问,小B的净收益最多是多少。
题解
网络流一般套路,新建源点汇点,所有点向汇点连容量为花费的边。在一个组合中,新建一个节点,源点向该点连流量为收益的边,该点向组合中的点连容量为INF的边。这样当选择该组内所有人时,若收益大于组合内的花费,则不会割掉收益的边,则最后答案为所有组合收益的和减去最大流。#include<cstdio> #include<algorithm> #include<cstdlib> #include<cstring> #include<queue> #define Set(a,b) memset(a,b,sizeof(a)) #define Copy(a,b) memcpy(a,b,sizeof(a)) using namespace std; inline int read() { int x=0;char ch=getchar();int t=1; for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=-1; for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48); return x*t; } const int M=220000; const int N=1000; typedef long long ll; const ll INF=1e9; struct edge{ int to,next;ll cap; }a[M<<1]; int head ; int cur ; int dis ; int cnt=0; inline void add(int x,int y,ll z) { a[cnt]=(edge){y,head[x],z}; head[x]=cnt++; } int tot; int n,m; int Q ; inline void clear(queue<int> &Q) { queue<int> P; swap(P,Q); } inline bool bfs() { register int h=1,t=1; Set(dis,-1);dis[0]=0;Q[1]=0; while(t>=h) { register int u=Q[h++]; for(register int v,i=head[u];i!=-1;i=a[i].next) { v=a[i].to; if(a[i].cap==0||dis[v]!=-1) continue; dis[v]=dis[u]+1; if(v==tot) return 1; Q[++t]=v; } } return (dis[tot]!=-1); } inline ll dfs(int u,ll flow) { if(u==tot) return flow; register ll delta=flow; for(register int v,&i=cur[u];i!=-1;i=a[i].next) { v=a[i].to; if(a[i].cap==0||dis[v]!=dis[u]+1) continue; register ll d=dfs(v,min(delta,a[i].cap)); delta-=d; a[i].cap-=d;a[i^1].cap+=d; if(d==0) dis[v]=0; if(delta==0) break; } return flow-delta; } inline void Dinic(ll sum) { register ll max_flow=0; while(bfs()) Copy(cur,head),max_flow+=dfs(0,INF); printf("%lld\n",sum-max_flow); } int main() { m=read();n=read(); Set(head,-1); register ll sum=0; register int x,y;register ll z;tot=n; for(register int i=1;i<=m;i++){ z=1ll*read();tot++;sum+=z; add(0,tot,z);add(tot,0,0); while(233){ x=read(); if(!x) break; add(tot,x,INF);add(x,tot,0); } } tot++; for(register int i=1;i<=n;i++){ z=1ll*read(); add(i,tot,z);add(tot,i,0); } Dinic(sum); }
相关文章推荐
- [Luogu 3410]拍照
- 【luogu 3410】拍照
- Android Camera2 拍照入门学习
- OpenCV控制摄像头实现 拍照功能
- Android自定义相机实现定时拍照
- 拍照裁剪报错 无法加载此图片
- webrtc,人脸拍照小功能
- 使用相机实现拍照
- Andriod 关于拍照及本地图片多选的那些事(下)
- Camera2拍照(备忘)
- webrtc,人脸拍照小功能
- 微信小程序实战开发:图片选取以及拍照功能
- 安卓拍照,各种兼容
- [luoguP3598]Koishi Loves Number Theory
- Android 仿照微信发说说,既能实现拍照,选图库,多图案上传 使用Retrofit2.0技术
- 实现手机App实现拍照功能
- 适配Android7.0的拍照,选取照片
- Android Camera2 拍照入门学习
- 利用摄像头拍照并保存
- C#Y实现调用摄像头拍照(过程中需要添加大量的引用)