Both the network flow problem take a formula:
Bottom line is that there are n people, there are two camps, divided people into camps there will be a corresponding value corresponding, may also have simultaneous value (that is, if the provisions of No. u chose A, v B have the additional option No. What is the value of);
This problem is often converted into a minimum cut problem, then ran out of the maximum flow, if the subject of the request is seeking the greatest value would be the answer to all sides in the sum minus the maximum flow
1 ) https://www.luogu.org/problem/P1361
Title Description
Small M in the MC opened up two huge farmland A and B (you can think of infinite capacity), now small P n in seed crops, seed crops each have one (is that you can grow a crop ) (with a number 1 ... n).
Now, the i-th crop planted in A revenue available ai and bi planting can get benefits in B, but now there is such an amazing phenomenon that some common types of crops can be cultivated land in one piece obtaining additional revenue, small m found a total of m crop combination rule, the i-th combination of crop species common additional benefits can be obtained c1i in a common total gain additional revenue c2i in B.
Small M quickly calculate the maximum benefit of planting, but he wanted to test you, can you answer his question it?
Input Format
The first line contains an integer n
The second row includes n integer representing ai third row includes n integer representing the fourth row comprising a bi Next integer m m rows,
For the next i-th row: ki first integer, denotes the i th of the total composition crop ki crops,
The next two integers c1i, c2i, ki next integer, indicates the number of crop combination.
Output Format
Only one line, including an integer representing the maximum benefit
题解:(1)https://www.cnblogs.com/butterflydew/p/9240393.html (2)https://blog.csdn.net/yzyyylx/article/details/79349244
#include <bits / STDC ++ H.> the using namespace STD; const int MAXN = 1e6 + 10 ; const int INF = 0x3f3f3f3f ; struct Edge { int from , to, CAP, Flow; Edge () {} Edge ( int from , int to, int CAP, int Flow): from ( from ), to (to), CAP (CAP), Flow (Flow) {} }; struct Dinic { int m, S, T; // number of nodes, the number of sides ( a reverse arc), a source and a sink point number Vector <Edge> Edges; // edge list edges [e] and the edges [e ^ 1] mutually reverse arc Vector < int > G [MAXN]; // adjacent table, G [i] [j] denotes the node No. edge e in the array of Article J i BOOL VIS [MAXN]; // the BFS use, if a node is traversed flag int D [MAXN]; // D [i] table from the starting point s to point i distance (level) int CUR [MAXN]; // CUR [i] is currently visiting the i-node table of CUR [i] arcs void the init ( int n-, int S, int T) { the this -> S = S, the this -> T = T; for ( int I = 0;i<=n;i++) G[i].clear(); edges.clear(); } void AddEdge(int from,int to,int cap) { edges.push_back( Edge(from,to,cap,0) ); edges.push_back( Edge(to,from,0,0) ); m = edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BFS() { memset(vis,0,sizeof(vis)); queue<int> Q;//用来保存节点编号的 Q.push(s); d[s]=0; vis[s]=true; while(!Q.empty()) { int x=Q.front(); Q.pop(); for(int i=0; i<G[x].size(); i++) { Edge& e=edges[G[x][i]]; if(!vis[e.to] && e.cap>e.flow) { VIS [e.to] = to true ; D [e.to] = D [X] + . 1 ; Q.push (e.to); } } } return VIS [T]; } // A represents a from s to So far all x minimal residual arc // Flow denotes the minimum residual from x to t int the DFS ( int x, int a) { IF (t || x == a == 0 ) return a; int Flow = 0 , F; // Flow from x to t to record the minimum residual for (int & CUR i = [X]; i <G [X] .size (); i ++) /// Note that the ampersand, so while increasing i values also change cur [u], the current reaches the recording the object of the arc { Edge & E = Edges [G [X] [I]]; IF (D [X] + . 1 == D [e.to] && (F = the DFS (e.to, min (a, E e.flow-.cap)))> 0 ) { e.flow + = F; Edges [G [X] [I] ^ . 1 ] .flow - = F; Flow + = F; A - = F; IF ( == A 0 ) BREAK ; } } if(!flow) d[x] = -1;///炸点优化 return flow; } int Maxflow() { int flow=0; while(BFS()) { memset(cur,0,sizeof(cur)); flow += DFS(s,inf); } return flow; } }DC; int sum,w; int main(void ) { int n,m;scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&w); sum+=w; DC.AddEdge(0,i,w); } for(int i=1 ; i<=n ; i++){ scanf("%d",&w); sum+=w; DC.AddEdge(i,n+1,w); } scanf("%d",&m); for(int i=1 ; i<=m ; i++){ int k,c1,c2; scanf("%d%d%d",&k,&c1,&c2); DC.AddEdge(0,i+n+1,c1);sum+=c1; DC.AddEdge(i+n+m+1,n+1,c2);sum+=c2; for(int j=1 ; j<=k ; j++){ int v; scanf("%d",&v); DC.AddEdge(i+n+1,v,inf); DC.AddEdge(v,i+n+m+1,inf); } } DC.s=0;DC.t=n+1; printf("%d",sum-DC.Maxflow()); }
2)http://acm.hdu.edu.cn/showproblem.php?pid=6598
Said that Italy is an army of n people, you can give each of them to arrange professional fighter or mage, there are m for people with a combination of skills, information technology is a combination of A, B, C, if the two men are representatives of two soldiers, the combined power of technology is a, a warrior mage, power is B, where B = a / 4 + C / 3, two Master, power is C, the maximum power demand.
题解: (1) https://www.cnblogs.com/isakovsky/p/11248963.html
(2) https://www.cnblogs.com/sainsist/p/11328601.html
#include <bits/stdc++.h> using namespace std; #define rep(i,a,n) for (int i=a;i<n;i++) #define per(i,a,n) for (int i=n-1;i>=a;i--) #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define fi first #define se second #define SZ(x) ((int)(x).size()) typedef vector<int> VI; typedef long long ll; typedef pair<int,int> PII; mt19937 mrand(random_device{}()); const ll mod=1000000007; int rnd(int x) { return mrand() % x;} ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;} const int maxn = 1e3+100; const int maxm = 1e5+100; const int inf = 0x7f7f7f7f; typedef struct Dinic { typedef struct Edge { int u,v,w,nxt; } Edge; int head[maxn],hcnt; int dep[maxn]; int cur[maxn]; Edge e[maxm]; int S,T,N; void init() { memset(head,-1,sizeof head); hcnt = 0; S = T = N = 0; } void adde(int u,int v,int w) { e[hcnt].u = u,e[hcnt].v = v,e[hcnt].w = w; e[hcnt].nxt = head[u];head[u] = hcnt++; e[hcnt].u = v,e[hcnt].v = u,e[hcnt].w = 0; e[hcnt].nxt = head[v];head[v] = hcnt++; } int bfs() { rep(i,0,N) { dep[i] = inf; } queue<int> q; q.push(S); dep[S] = 0; while(!q.empty()) { int u = q.front();q.pop(); for(int i = head[u];~i;i = e[i].nxt) { int v = e[i].v,w = e[i].w; if(w > 0 && dep[u] + 1 < dep[v]) { dep[v] = dep[u] + 1; if(v == T) { return 1; } q.emplace(v); } } } return dep[T] != inf; } int dfs(int s,int mw) { if(s == T) return mw; for(int i = cur[s];~i;i=e[i].nxt) { cur[s] = i; int v = e[i].v,w=e[i].w; if(w <= 0 || dep[v] != dep[s] + 1) { continue; } int cw = dfs(v,min(w,mw)); if(cw <= 0) continue; e[i].w -= cw; e[i^1].w += cw; return cw; } return 0; } ll dinic() { ll res = 0; while(bfs()) { rep(i,0,N) { cur[i] = head[i]; } while(int d = dfs(S,inf)) { res += 1ll * d; } } return res; } } Dinic; int n,m,s,t; ll w[maxn],ww[maxn]; int main(int argc, char const *argv[]) { while(scanf("%d%d",&n,&m)!=EOF) { memset(w,0,sizeof w);memset(ww,0,sizeof ww); Dinic din;din.init(); s = 0,t = n+1; din.S = 0,din.T = n+1,din.N = n+10; int u,v; ll a,b,c; ll ans = 0; rep(i,0,m) { scanf("%d%d%lld%lld%lld",&u,&v,&a,&b,&c); // cout << "---------" << endl; w[u] += b+c;w[v]+=b+c; ww[u] += a+b;ww[v]+=a+b; din.adde(u,v,a+c-2*b); din.adde(v,u,a+c-2*b); ans += a + b + c; } // cout << ans << endl; rep(i,1,n+1) { din.adde(s,i,w[i]); din.adde(i,t,ww[i]); } printf("%lld\n",ans-din.dinic()/2 ); } return 0; }
The subject of much have to do ah