【BZOJ】1497 [NOI2006]最大获利
2017-03-23 12:03
429 查看
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1497
经典的网络流
割边表示舍弃该价值,所以可以把用户群的收益连向一边,建站的费用连向一边,中间把对应点连inf
这样的最小割就是最小舍弃的价值,加上总获利就是最大获利了
经典的网络流
割边表示舍弃该价值,所以可以把用户群的收益连向一边,建站的费用连向一边,中间把对应点连inf
这样的最小割就是最小舍弃的价值,加上总获利就是最大获利了
#include<stdio.h> #include<algorithm> #include<cstring> #define cint const int & #define inf 2333333 #define N 55005 using namespace std; int tot=1,Q ,s ,cur ,lev ,tm ,ts,n,m,a,b,w,ans; struct edge{int v,c,n;}e[N*6]; inline void push(cint u,cint v,cint c) { e[++tot]=(edge){v,c,s[u]};s[u]=tot; e[++tot]=(edge){u,0,s[v]};s[v]=tot; } inline bool bfs() { memcpy(cur,s,sizeof(cur)); tm[Q[1]=1]=++ts; for (int l=1,r=1;l<=r;l++) for (int i=s[Q[l]];i;i=e[i].n) if (e[i].c && tm[e[i].v]<ts) tm[Q[++r]=e[i].v]=ts,lev[Q[r]]=lev[Q[l]]+1; return tm[n+m+2]==ts; } int dfs(cint u,int c) { if (u==n+m+2) return c; int g=0,tmp; for (int i=cur[u];i && c;cur[u]=i,i=e[i].n) if (tm[e[i].v]==ts && lev[e[i].v]==lev[u]+1 && e[i].c && (tmp=dfs(e[i].v,min(c,e[i].c)))) g+=tmp,c-=tmp,e[i].c-=tmp,e[i^1].c+=tmp; return g; } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&w),push(1,i+1,w); for (int i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&w); ans+=w; push(a+1,n+1+i,inf); push(b+1,n+1+i,inf); push(n+1+i,n+m+2,w); } while (bfs()) for (int rt=dfs(1,inf);rt;rt=dfs(1,inf)) ans-=rt; printf("%d",ans); }
相关文章推荐
- 【Dinic】bzoj1497 noi2006 最大获利
- bzoj 1497: [NOI2006]最大获利 最小割 最大权闭和子图
- bzoj 1497: [NOI2006]最大获利
- bzoj1497[NOI2006]最大获利
- 最大权闭合图 && 【BZOJ】1497: [NOI2006]最大获利
- bzoj 1497: [NOI2006]最大获利 最小割
- 【BZOJ 1497】 [NOI2006]最大获利
- BZOJ_1497_[NOI2006]_最大获利_(最大流+最大权闭合图)
- AC日记——[NOI2006]最大获利 bzoj 1497
- [BZOJ 1497][NOI2006]最大获利(最大权闭合图)
- [BZOJ1497][NOI2006]最大获利(最大权闭合子图)
- BZOJ 1497[NOI 2006] 最大获利
- 【BZOJ1497】【NOI2006】最大获利(网络流)
- BZOJ 1497 [NOI2006] 最大获利
- 【BZOJ】1497 [NOI2006]最大获利 网络流
- bzoj 1497 [NOI2006]最大获利【最大权闭合子图+最小割】
- [BZOJ 1497][NOI 2006]最大获利(最大权闭合子图)
- Bzoj 1497: [NOI2006]最大获利(最小割)
- BZOJ 1497 [NOI2006]最大获利 (最小割)
- [NOI2006]最大获利 BZOJ1497 - 最小割