ZOJ 3229 Shoot the Bullet

The meaning of the question: a person wants to take pictures of girls, a total of n days, m girls, every day he takes at most d[i] pictures, each girl must be photographed at least g[i] times in total. On the i-th day, c[i] girls can be photographed, and the number of times each girl in the c[i] girls is photographed on that day is [li,ri]. Find the maximum number of pictures that can be taken, and the number of times each girl can be photographed each day. How many pictures were taken of each girl who could be photographed.

Analysis: An obvious network flow, it is easy to build a map, establish a source point s and a sink point t, and then s is connected to each day with an edge, the upper bound of capacity is d[i], and each girl is connected to the sink point. , the lower bound is g[i], the upper bound is infinity, and then for each day, from the node of each day to the girl, connect an edge whose upper bound is ri, and the lower bound is li, and then the graph is built. , is to seek the maximum flow, but this is not an ordinary network flow, we have to convert it, first of all, based on passive and no sink, build, because it is a source sink, so connect an edge t -> s, INF, Then find the maximum flow of the super source point and sink (note that it is not st) ST. If the flow is full, there is a feasible flow, and then find the maximum flow of s->t, and the result is the answer. Then output the solution, and when the solution is output, it is the flow plus the upper and lower bounds.

code show as below:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#include <list>
#include <assert.h>
#include <bitset>
#include <numeric>
#define debug() puts("++++")
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a, b, sizeof a)
#define sz size()
#define be begin()
#define ed end()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
//#define all 1,n,1
#define FOR(i,n,x)  for(int i = (x); i < (n); ++i)
#define freopenr freopen("in.in", "r", stdin)
#define freopenw freopen("out.out", "w", stdout)
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e17;
const double inf = 1e20;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1500 + 50;
const int maxm = 1e6 + 10;
const LL mod = 1000000007;
const int dr[] = {-1, 1, 0, 0, 1, 1, -1, -1};
const int dc[] = {0, 0, 1, -1, 1, -1, 1, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int my[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c) {
  return r >= 0 && r < n && c >= 0 && c < m;
}
inline int readInt(){ int x;  scanf("%d", &x);  return x; }

struct Edge{
  int from, to, cap, flow;
};

struct Dinic{
  int n, m, s, t;
  vector<Edge> edges;
  vector<int> G[maxn];
  bool vis[maxn];
  int d[maxn];
  int cur[maxn];
  
  void init(int n){
    FOR(i, n, 0)  G[i].cl;
    edges.cl;
  }
  
  void addEdge(int from, int to, int cap){
    edges.pb((Edge){from, to, cap, 0});
    edges.pb((Edge){to, from, 0, 0});
    m = edges.sz;
    G[from].pb(m - 2);
    G[to].pb(m - 1);
  }
  
  bool bfs(){
    ms(vis, 0); d[s] = 0; screw[s] = 1;
    queue<int> q;  q.push(s);
    
    while(!q.empty()){
      int u = q.front();  q.pop();
      for(int i = 0; i < G[u].sz; ++i){
        Edge &e = edges[G[u][i]];
        if(!vis[e.to] && e.cap > e.flow){
          vis [e.to] = 1;
          d[e.to] = d[u] + 1;
          q.push(e.to);
        }
      }
    }
    return vis[t];
  }
  
  int dfs (int u, int a) {
    if(u == t || a == 0)  return a;
    int flow = 0, f;
    for(int &i = cur[u]; i < G[u].sz; ++i){
      Edge &e = edges[G[u][i]];
      if(d[e.to] == d[u] + 1 && (f = dfs(e.to, min(a, e.cap-e.flow))) > 0){
        e.flow += f;
        edges[G[u][i]^1].flow -= f;
        flow += f;
        a -= f;
        if(a == 0)  break;
      }
    }
    return flow;
  }
  
  int maxFlow(int s, int t){
    this->s = s; this->t = t;
    int flow = 0;
    while(bfs()){ ms(cur, 0);  flow += dfs(s, INF); }
    return flow;
  }
};
Dinic dinic;

int down[100000], in[100000], d[maxn], g[maxn];

int main(){
  while(scanf("%d %d", &n, &m) == 2){
    int s = 0, t = n + m + 1;
    dinic.init(t + 10);
    ms(in, 0);
    for(int i = 1; i <= m; ++i)
      scanf("%d", g + i);
    
    int cnt = 0;
    for(int i = 1; i <= n; ++i){
      int c;  scanf("%d %d", &c, d + i);
      int x, l, r;
      while(c--){
        scanf("%d %d %d", &x, &l, &r);
        down[cnt++] = l;
        dinic.addEdge(i, x + n + 1, r - l);
        in[i] -= l;
        in[x+n+1] += l;
      }
    }
    for(int i = 1; i <= n; ++i)
      dinic.addEdge(s, i, d[i]);
    for(int i = 1; i <= m; ++i){
      dinic.addEdge(i + n, t, INF - g[i]);
      in[i+n] -= g[i];
      in[t] += g[i];
    }
    int S = t + 1, T = t + 2;
    int years = 0;
    for(int i = 0; i <= t; ++i)
      if(in[i] > 0)  dinic.addEdge(S, i, in[i]), ans += in[i];
      else if(in[i] < 0)  dinic.addEdge(i, T, -in[i]);
    dinic.addEdge(t, s, INF);
    if(ans != dinic.maxFlow(S, T)){ printf("-1\n\n");  continue; }
    printf("%d\n", dinic.maxFlow(s, t));
    for(int i = 0; i < cnt; ++i)  printf("%d\n", dinic.edges[i<<1].flow + down[i]);
    printf("\n");
  }
  return 0;
}

  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325095066&siteId=291194637
ZOJ
ZOJ