Https://www.lydsy.com/JudgeOnline/problem.php? Id = 106152
When it is not easy to create a graph for multiple vertices, consider reverse thinking.
After successfully applying for the Olympic Games, bu made unremitting efforts and finally became the supervisor of the HR department of the organizing committee. Bu encountered a difficult problem when he took office: recruiting a group of short-term volunteers for the upcoming New Olympic project. It is estimated that this project will take n days to complete, and the day I will require at least AI individuals. Bu learned that a total of M volunteers can be recruited. Category I can work from the SI day to the Ti day, and the recruitment fee is CI yuan per person. In order to do his job well, bu hopes to recruit enough volunteers at a low cost, but this is not his specialty! So Bu found you and hoped that you could help him design an optimal recruitment solution. The first line of input contains two integers, n, m, indicating the number of days of completion of the project and the types of volunteers that can be recruited. The next row contains N non-negative integers, indicating at least the number of volunteers required each day. Each row in the next m row contains three integers, Si, Ti, and CI. The meaning is described above. For convenience, we can consider that the number of volunteers for each type is infinite. The output contains only one integer, indicating the total cost of the optimal solution you have designed. Sample input3 32 3 41 2 22 3 53 3 2 Sample output14hint1 ≤ n ≤ 10000, 1 ≤ m ≤, and other data involved in the question shall not exceed 2 ^ 31-1.
Question
Although I know this is a charge flow after reading the questions, I never thought of how to create a picture. I read the question when I thought it was impossible to create a picture.
Only then can we know that the world is great.
In the original normal graph creation, the source point is connected to the left, and the volunteers are connected to the corresponding days, but there will be a lot of sides first, and the cost is difficult to express, the process of creating a graph is difficult.
But if you use another method.
We changed the number of Volunteers needed at this point into the number of volunteers who reached the standard at this point. We set the standard to a large constant U. It seems that there is no difference, but in fact we exit u from the source point, after each day is equivalent to the U-A [I] limit, the traffic will be reduced, we need volunteers to make her flow out, so for a volunteer from L to R, we just need to build an edge from L to R + 1 at a cost of W, this volunteer fills in the vacancy from L to R.
It's amazing.
#include <map>#include <set>#include <ctime>#include <cmath>#include <queue>#include <stack>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <sstream>#include <iostream>#include <algorithm>#include <functional>using namespace std;inline int read(){int now=0;register char c=getchar();for(;!isdigit(c);c=getchar());for(;isdigit(c);now=now*10+c-‘0‘,c=getchar());return now;}#define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--)#define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x)#define Sca2(x,y) scanf("%d%d",&x,&y)#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)#define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d\n", x)#define Prl(x) printf("%lld\n",x); #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();#define LL long long#define ULL unsigned long long #define mp make_pair#define PII pair<int,int>#define PIL pair<int,long long>#define PLL pair<long long,long long>#define pb push_back#define fi first#define se second typedef vector<int> VI;const double eps = 1e-9;const int maxn = 1e5 + 10;const int maxm = 2e5 + 10;const int INF = 0x3f3f3f3f;const int U = 1e5 + 10;const int mod = 1e9 + 7; int N,M,K;struct MCMF{ struct Edge{ int from,to,cap,flow,nxt; LL cost; Edge() {} Edge(int x,int y,int z,int u,LL v,int n){ from = x; to = y; cap = z; flow = u; cost = v; nxt = n; } }edge[maxm]; int E,n,head[maxn]; int inq[maxn],d[maxn],p[maxn],a[maxn]; inline void init(int _n){ n = _n;E = 0; memset(head,-1,sizeof(head)); } inline void addEdge(int f,int t,int c,LL w){ edge[E] = Edge(f,t,c,0,w,head[f]); head[f] = E++; edge[E] = Edge(t,f,0,0,-w,head[t]); head[t] = E++; } bool spfa(int s,int t,int &flow,LL &cost){ for(int i = 0 ; i <= n ; i ++) d[i] = INF; memset(inq,0,sizeof(inq)); d[s] = 0;inq[s] = 1;p[s] = 0;a[s] = INF; queue<int>Q; Q.push(s); while(!Q.empty()){ int u = Q.front(); Q.pop(); inq[u] = 0; for(int i = head[u]; ~i; i = edge[i].nxt){ Edge &e = edge[i]; if(e.cap <= e.flow || d[e.to] <= d[u] + e.cost) continue; d[e.to] = d[u] + e.cost; p[e.to] = i; a[e.to] = min(a[u],e.cap - e.flow); if(!inq[e.to]){ Q.push(e.to); inq[e.to] = 1; } } } if(d[t] == INF) return false; flow += a[t]; cost += (LL)d[t] * (LL)a[t]; for(int u = t; u != s; u = edge[p[u]].from){ edge[p[u]].flow += a[t]; edge[p[u] ^ 1].flow -= a[t]; } return true; } int mcmf(int s,int t,LL &cost){ int flow = 0; cost = 0; while(spfa(s,t,flow,cost)); return flow; }}g;int main(){ Sca2(N,M); int s = 0,t = N + 1; g.init(t + 1); g.addEdge(s,1,U,0); For(i,1,N){ LL x; Scl(x); g.addEdge(i,i + 1,U - x,0); } while(M--){ int l,r; LL c; Sca2(l,r); Scl(c); g.addEdge(l,r + 1,INF,c); } LL cost = 0; g.mcmf(s,t,cost); Prl(cost); #ifdef VSCode system("pause"); #endif return 0;}
Bzoj1061 graph creation + minimum cost flow