• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
dwtfukgv
博客园    首页    新随笔    联系   管理    订阅  订阅
UVa 11167 Monkeys in the Emei Mountain (最大流)

题意:雪雪是一只猴子。它在每天的 2:00 —— 9:00之间非常渴,所以在这个期间它必须喝掉2个单位的水。它可以多次喝水,只要它喝水的总量是2.它从不多喝,在一小时内他只能喝一个单位的水。所以它喝水的时间段可能是2:00 ——4:00,或者3:00——5:00,或者7:00——9:00.甚至喝两次,第一次2:00——3:00,第二次8:00——9:00.但是它不能在1:00——3:00喝水,因为在1:00时它不渴,也不能在8:00——10:00喝水,因为9:00必须结束。一共有n(n <= 100)只这样的猴子。我们用一个(v,a,b)(0 <= v,a,b <= 50000,a < b,v <= b - a)来描述一个在时间a~b之间口渴,并且必须在这个期间喝够v个单位水的猴子。所有猴子喝水的速度都是1小时喝1个单位的水。现在的问题是只有一个地方可以让m只猴子同时喝水,需要作出一个能满足所有猴子的喝水需要的安排,问能否给出安排。多解时输出任意一组解即可。

析:很明显的把每只猴子都看作一个结点,然后把每个时间也是看成一个结点,但是,,,太多了吧,肯定会爆炸的,所以,先把所有的区间进行离散化,然后对每个区间建立结点,在输出解的时候,要注意,把所有的区间进行合并,只要对每个区间都加一个标志,循环标记,每次都加一个段,因为最大流最大的情况就是把整个区间都充满,不会超过。

代码如下:

#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 pu push_up
#define pd push_down
#define cl clear()
#define all 1,n,1
#define FOR(i,x,n)  for(int i = (x); i < (n); ++i)
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "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-3;
const int maxn = 500 + 10;
const int maxm = 1e7 + 10;
const int mod = 1000000007;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, -1, 0, 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 mon[] = {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;
}

struct Edge{
  int from, to, cap, flow;
};
struct Dinic{
  int n, m, s, t;
  vector<Edge> edges;
  vector<int> G[maxn];
  int d[maxn];
  bool vis[maxn];
  int cur[maxn];

  void init(int n){
    this-> n = n;
    for(int i = 0; i < n; ++i)  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);  vis[s] = 1;  d[s] = 0;
    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;
vector<int> val;
int v[maxn], a[maxn], b[maxn];
int cnt[maxn];

int getpos(int x){ return lower_bound(val.begin(), val.end(), x) - val.begin(); }

int main(){
  int kase = 0;
  while(scanf("%d", &n) == 1 && n){
    scanf("%d", &m);
    val.cl;  val.pb(-1);
    int sum = 0;
    for(int i = 1; i <= n; ++i){
      scanf("%d %d %d", v+i, a+i, b+i);
      val.pb(a[i]);  val.pb(b[i]);
      sum += v[i];
    }
    sort(val.begin(), val.end());
    val.resize(unique(val.begin(), val.end()) - val.begin());
    int len = val.sz;
    int s = 0, t = len + n + 3;
    dinic.init(t + 5);
    for(int i = 1; i <= n; ++i){
      dinic.addEdge(s, len+i, v[i]);
      int l = getpos(a[i]);
      int r = getpos(b[i]);
      for(int j = l; j < r; ++j)  dinic.addEdge(len+i, j, val[j+1]-val[j]);
    }
    for(int j = 1; j + 1 < len; ++j)  dinic.addEdge(j, t, (val[j+1]-val[j])*m);
    if(sum != dinic.maxflow(s, t))  printf("Case %d: No\n", ++kase);
    else{
      printf("Case %d: Yes\n", ++kase);
      for(int i = 0; i < len; ++i)  cnt[i] = val[i];
      for(int i = 1; i <= n; ++i){
        vector<P> ans;
        for(int j = 0; j < dinic.G[i+len].sz && v[i]; ++j){
          Edge &e = dinic.edges[dinic.G[i+len][j]];
          if(e.from != i + len)  continue;
          int x = dinic.edges[dinic.G[i+len][j]^1].flow;
          if(x >= 0)  continue;
          x = -x;  v[i] -= x;
          if(val[e.to] + x < val[e.to+1]){
            if(x + cnt[e.to] <= val[e.to+1]){
              ans.push_back(P(cnt[e.to], cnt[e.to] + x));
              cnt[e.to] += x;
              if(cnt[e.to] == val[e.to+1])  cnt[e.to] = val[e.to];
            }
            else{
              x -= val[e.to+1] - cnt[e.to];
              ans.push_back(P(cnt[e.to], val[e.to+1]));
              cnt[e.to] = val[e.to] + x;
              ans.push_back(P(val[e.to], cnt[e.to]));
            }
          }
          else  ans.push_back(P(val[e.to], val[e.to+1]));
        }
        sort(ans.begin(), ans.end());
        for(int j = 0; j + 1 < ans.sz; ){
          if(ans[j].se == ans[j+1].fi)  ans[j].se = ans[j+1].se, ans.erase(ans.begin()+j+1);
          else ++j;
        }
        printf("%d", ans.sz);
        for(int j = 0; j < ans.sz; ++j)  printf(" (%d,%d)", ans[j].fi, ans[j].se);
        printf("\n");
      }
    }
  }
  return 0;
}

  

posted on 2017-10-31 12:53  dwtfukgv  阅读(466)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3