【洛谷1361】 小M的作物(最小割)
生活随笔
收集整理的這篇文章主要介紹了
【洛谷1361】 小M的作物(最小割)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
傳送門
洛谷
Solution
這是一個比較實用的套路,很多題目都有用,而且這個套路難以口胡出來。
考慮把每一個附加貢獻重新建一個點,然后向必需的點連邊,流量為val。
然后直接種植的從源點向這個點連,流量為val。
最后跑一個最小割就可以了。
代碼實現
#include<bits/stdc++.h> using namespace std; const int N=500010,Inf=1e9+10; int front[N],cnt,s,t,n; struct node {int to,nxt,w; }e[1500010]; queue<int>Q; int dep[N]; void Add(int u,int v,int w) {e[cnt]=(node){v,front[u],w};front[u]=cnt++;e[cnt]=(node){u,front[v],0};front[v]=cnt++; } bool bfs() {memset(dep,0,sizeof(dep));Q.push(s);dep[s]=1;while(!Q.empty()){int u=Q.front();Q.pop();for(int i=front[u];i!=-1;i=e[i].nxt){int v=e[i].to;if(!dep[v] && e[i].w){dep[v]=dep[u]+1;Q.push(v);}} }return dep[t]; } int dfs(int u,int flow) {if(u==t || !flow)return flow;for(int i=front[u];i!=-1;i=e[i].nxt){int v=e[i].to;if(dep[v]==dep[u]+1 && e[i].w){int di=dfs(v,min(flow,e[i].w));if(di){e[i].w-=di;e[i^1].w+=di;return di;}else dep[v]=0;}}return 0; } int dinic() {int flow=0;while(bfs()){while(int d=dfs(s,Inf))flow+=d;}return flow; } int m; int main() {memset(front,-1,sizeof(front));scanf("%d",&n);int sum=0;t=100000;int tot=n;for(int i=1;i<=n;i++){int x;scanf("%d",&x);sum+=x;Add(s,i,x);}for(int i=1;i<=n;i++){int x;scanf("%d",&x);sum+=x;Add(i,t,x);}scanf("%d",&m);while(m--){int k,c1,c2;scanf("%d%d%d",&k,&c1,&c2);++tot;Add(s,tot,c1);Add(tot+1,t,c2);sum+=c1+c2;for(int i=1;i<=k;i++){int id;scanf("%d",&id);Add(tot,id,Inf);Add(id,tot+1,Inf);}++tot;}printf("%d\n",sum-dinic());return 0; }轉載于:https://www.cnblogs.com/mle-world/p/10549703.html
總結
以上是生活随笔為你收集整理的【洛谷1361】 小M的作物(最小割)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 异步和多线程
- 下一篇: JS OOP -02 深入认识JS中的函