http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3229
题意:报社给M个妹子拍照,并且拍照N天,每一天给给定的C个妹子拍照,每天拍照数量不能超过D张,并且给每个妹子拍照的数量有限制(l,r),所有妹子n天总共拍的照片不能小于Gi张,求最多可以拍多少张照以及拍照方案
题意里这么多限制条件,考虑建图用上下界网络流做。
模型:设置一个起点对每一天连一条[0,D]的边,每一天向对应的被拍照的妹子连一条(l,r)的边,然后设置一个终点,将每个妹子向终点连一条(G,INF)的边
当然建图不是这么建,在上述模型上用有源汇的最大流就可以了
#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; #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 ", x) #define Prl(x) printf("%lld ",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; int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();} while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;} const double eps = 1e-9; const int maxn = 5010; const int maxm = 5e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; int a[maxn],F[maxm]; struct dinic{ struct Edge{ int to,next,cap,flow,id; Edge(){} Edge(int to,int next,int cap,int flow,int id): to(to),next(next),cap(cap),flow(flow),id(id){} }edge[maxm * 2]; int head[maxn],tot,cur[maxn],s,t,n,dep[maxn]; void init(int n){ this->n = n; for(int i = 0 ; i <= n ; i ++) head[i] = -1; tot = 0; } void add(int u,int v,int w,int id){ edge[tot] = Edge(v,head[u],w,0,id); head[u] = tot++; edge[tot] = Edge(u,head[v],0,0,id); head[v] = tot++; } inline bool bfs(){ for(int i = 0 ; i <= n ; i ++) dep[i] = -1; dep[s] = 1; queue<int>Q; Q.push(s); while(!Q.empty()){ int u = Q.front(); Q.pop(); for(int i = head[u]; ~i ; i = edge[i].next){ int v = edge[i].to; if(~dep[v] || edge[i].flow >= edge[i].cap) continue; dep[v] = dep[u] + 1; Q.push(v); } } return ~dep[t]; } inline int dfs(const int &u,int a){ if(u == t || !a) return a; int flow = 0; for(int &i = cur[u];~i ; i = edge[i].next){ int v = edge[i].to; if(dep[v] != dep[u] + 1) continue; int f = dfs(v,min(a,edge[i].cap - edge[i].flow)); flow += f; a -= f; edge[i].flow += f; edge[i ^ 1].flow -= f; //cout << a<< endl; if(!a) return flow; } return flow; } int maxflow(int s,int t){ this->s = s; this->t = t; int flow = 0; while(bfs()){ for(int i = 0 ;i <= n ; i ++) cur[i] = head[i]; flow += dfs(s,INF); } return flow; } void solve(){ for(int i = 0; i <= n ; i ++){ for(int j = head[i]; ~j ; j = edge[j].next){ int v = edge[j].to; if(edge[j].flow > 0) F[edge[j].id] = edge[j].flow; } } } void del(int S,int T,int SS,int TT){ for(int i = head[T]; ~i; i = edge[i].next){ if(edge[i].cap == INF){ edge[i].cap = edge[i].flow = 0; edge[i ^ 1].cap = edge[i ^ 1].flow = 0; break; } } for(int i = head[SS]; ~i; i = edge[i].next){ edge[i].cap = edge[i].flow = 0; edge[i ^ 1].cap = edge[i ^ 1].flow = 0; } for(int i = head[TT]; ~i; i = edge[i].next){ edge[i].cap = edge[i].flow = 0; edge[i ^ 1].cap = edge[i ^ 1].flow = 0; } } }g; int e[maxm]; int main(){ while(~Sca2(N,M)){ for(int i = 0; i <= N + M + 4; i ++)a[i] = 0; int s = M + N + 1,t = N + M + 2; int SS = N + M + 3,TT = N + M + 4; g.init(N + M + 4); for(int i = 1; i <= M ; i ++){ int G; Sca(G); g.add(N + i,t,INF - G,0); a[t] -= G; a[N + i] += G; } int cnt = 0; for(int i = 1; i <= N ; i ++){ int c,d; Sca2(c,d); g.add(s,i,d,0); for(int j = 1; j <= c; j ++){ int id,l,r; Sca3(id,l,r); id = id + 1 + N; g.add(i,id,r - l,++cnt); e[cnt] = l; a[id] -= l; a[i] += l; } } for(int i = 0 ; i <= cnt + 1; i ++) F[i] = 0; g.add(t,s,INF,cnt + 1); int sum = 0; for(int i = 1; i <= N + M + 2; i ++){ if(a[i] > 0){ g.add(i,TT,a[i],0); sum += a[i]; }else if(a[i] < 0){ g.add(SS,i,-a[i],0); } } if(sum != g.maxflow(SS,TT)){ puts("-1"); }else{ g.solve(); g.del(s,t,SS,TT); int ans = g.maxflow(s,t) + F[cnt + 1]; Pri(ans); g.solve(); for(int i = 1; i <= cnt; i ++){ Pri(F[i] + e[i]); } } puts(""); } return 0; }