HDU3605: Escape-二进制优化建图-最大流

目录

  • 目录
  • 思路:

(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

目录

题意:传送门

?原题目描述在最下面。
?\(n(n\leq 100000)\)个人\(m(m\leq 10)\)个星球,每个星球容纳的人数有上限,每个人都有自己想去的星球意愿。问是否所有的都能去到外星球。

思路:

?肯定不能暴力建图,因为人太多了。注意到m的大小只有10。刷过状压dp的人应该都能想到要二进制优化。
?这是每个人其实都是没有区别的,有区别的只是他们的意愿。然后最多也只有\(2^{10} =1024\)种意愿。那就把这些当作\(1000\)多个点嘛。记录每种状态的人数。

  • 超级源点S向每个星球连边,边容量为星球限值。
  • 每个星球向对它有意愿的人点连边,流量为这些人的数量,这个我们之前预处理出来了。
  • 然后\(2^m\)的状态点向超级汇点连边,流量为此状态的人数。

细节见代码。

AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define mme(a,b) memset((a),(b),sizeof((a)))
#define fuck(x) cout<<"* "<<x<<"\n"
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int MXN = 1e4+7;
const int MXE = 1e7+7;
struct DINIC{
  int tot,vt,vs;
  int d[MXN],head[MXN];
  struct lp{
    int to,w,nex;
  }cw[MXE];
  void add_edge(int a,int b,int c){
    cw[++tot].to=b;cw[tot].nex=head[a],cw[tot].w=c;
    head[a]=tot;
    cw[++tot].to=a;cw[tot].nex=head[b],cw[tot].w=0;
    head[b]=tot;
  }
  bool bfs(){
    memset(d,-1,sizeof(d));
    queue<int>Q;
    Q.push(vt);d[vt]=0;
    while(!Q.empty()){
      int u=Q.front();
      Q.pop();
      for(int i=head[u];i!=-1;i=cw[i].nex){
        int v=cw[i].to;
        if(cw[i^1].w&&d[v]==-1){
          d[v]=d[u]+1;
          Q.push(v);
        }
      }
    }
    return d[vs]!=-1;
  }
  int dfs(int x,int f){
    if(x==vt||f==0) return f;
    int use=0,w;
    for(int i=head[x];i!=-1;i=cw[i].nex){
      int to=cw[i].to;
      if(d[to]==d[x]-1 && cw[i].w){
        w=dfs(to,min(cw[i].w,f-use));
        cw[i].w-=w,cw[i^1].w+=w;
        use+=w;
        if(use==f) return f;
      }
    }
    return use;
  }
  void init(int st,int ed){
    tot=-1;
    memset(head,-1,sizeof(head));
    vs=st;vt=ed;
  }
  int max_flow(){
    int ans=0;
    while(bfs())ans+=dfs(vs,INF);
    return ans;
  }
}dinic;
int n, m;
int vs, vt;
int num[1<<11];
int main(){
  while(~scanf("%d%d",&n,&m)){
    int state = 1<<m;
    mme(num,0);
    vs=state+m+1,vt=state+m+2;
    dinic.init(vs,vt);
    for(int i=1;i<=n;++i){
      int tmp=0;
      for(int j=1;j<=m;++j){
        int x;scanf("%d",&x);
        if(x)tmp|=(1<<(j-1));
      }
      num[tmp]++;
    }
    for(int i=1;i<=m;++i){
      int x;scanf("%d",&x);
      dinic.add_edge(vs,i+state,x);
    }
    for(int i=1;i<state;++i){
      if(num[i]==0)continue;
      dinic.add_edge(i,vt,num[i]);
      for(int j=0;j<m;++j){
        if(i&(1<<j)){
          dinic.add_edge(state+j+1,i,num[i]);
        }
      }
    }
    LL ans = dinic.max_flow();
    if(ans>=n)printf("YES\n");
    else printf("NO\n");
  }
  return 0;
}

原题目描述:

Problem Description
2012 If this is the end of the world how to do? I do not know how. But now scientists have found that some stars, who can live, but some people do not fit to live some of the planet. Now scientists want your help, is to determine what all of people can live in these planets.

Input
More set of test data, the beginning of each data is n (1 <= n <= 100000), m (1 <= m <= 10) n indicate there n people on the earth, m representatives m planet, planet and people labels are from 0. Here are n lines, each line represents a suitable living conditions of people, each row has m digits, the ith digits is 1, said that a person is fit to live in the ith-planet, or is 0 for this person is not suitable for living in the ith planet.
The last line has m digits, the ith digit ai indicates the ith planet can contain ai people most..
0 <= ai <= 100000

Output
Determine whether all people can live up to these stars
If you can output YES, otherwise output NO.

Sample Input
1 1
1
1

2 2
1 0
1 0
1 1

Sample Output
YES
NO

Source
2010 ACM-ICPC Multi-University Training Contest(17)——Host by ZSTU

Recommend
lcy

原文地址:https://www.cnblogs.com/Cwolf9/p/9418994.html

时间: 2024-08-30 01:20:47

HDU3605: Escape-二进制优化建图-最大流的相关文章

【bzoj4276】[ONTAK2015]Bajtman i Okr?g?y Robin 线段树优化建图+费用流

题目描述 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2],...,[b[i]-1,b[i]]这么多段长度为1时间中选出一个时间进行抢劫,并计划抢走c[i]元.作为保安,你在每一段长度为1的时间内最多只能制止一个强盗,那么你最多可以挽回多少损失呢? 输入 第一行包含一个正整数n(1<=n<=5000),表示强盗的个数. 接下来n行,每行包含三个正整数a[i],b[i],c[i](1<=a[i]<b[i]<=5000,1<=c[i]

BZOJ 3218 A+B Problem(最大流 + 主席树优化建图)

题目:A+B Problem 感谢 Nietzsche 在省选紧迫之际花 39' 给我讲这道题. 这题我并没有想出来,感觉又浪费一道好题了. 需要用最小割,建模方式如下(假设若 2 取黑色,1 取白色会使 2 为奇怪方格): 跑一边最大流,求出最小割,用所有的 W + 所有的 B - 最小割,就是答案. 不过,对于每一个结点 2,在寻找像 1 这样(li <= aj <= ri)的结点时,总不能一个一个枚举吧? O(n2) T 飞. 所以,需要用主席树优化一下.线段树优化建图笔记. 代码未完待

【BZOJ3681】Arietta 树链剖分+可持久化线段树优化建图+网络流

[BZOJ3681]Arietta Description Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中.但是她从未停止过和恋人 Velding 的书信往来.一天,她准备去探访他.对着窗外的阳光,临行前她再次弹起了琴.她的琴的发声十分特殊.让我们给一个形式化的定义吧.所有的 n 个音符形成一棵由音符 C ( 1 号节点) 构成的有根树,每一个音符有一个音高 Hi .Arietta 有 m 个力度,第 i 个力度能弹出 Di 节点的子树中,音高在 [Li,R

【bzoj3073】[Pa2011]Journeys 线段树优化建图+堆优化Dijkstra

题目描述 Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建造道路:(a,b),(c,d)表示,对于任意两个国家x,y,如果a<=x<=b,c<=y<=d,那么在xy之间建造一条道路.Seter保证不会有一个国家与自己之间有道路. Seter好不容易建好了所有道路,他现在在位于P号的首都.Seter想知道P号国家到任意一个国家最少需要经过几条道路.当然,Se

HDU 4292 Food(建图+最大流)

使用 PVRTC 压缩格式创建纹理(Creating textures in the PVRTC compression format) 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS.Android.Html5.Arduino.pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 有关该篇

【ARC069F】Flags 2-sat+线段树优化建图+二分

Description ? 数轴上有 n 个旗子,第 ii 个可以插在坐标 xi或者 yi,最大化两两旗子之间的最小距离. Input ? 第一行一个整数 N. ? 接下来 N 行每行两个整数 xi,yi Output ? 一个整数表示答案. Sample Input Sample #1 3 1 3 2 5 1 9 Sample #2 5 2 2 2 2 2 2 2 2 2 2 Sample #3 22 93 6440 78 6647 862 11 8306 9689 798 99 801 52

Codeforces 787D. Legacy 线段树优化建图+最短路

output standard output Rick and his co-workers have made a new radioactive formula and a lot of bad guys are after them. So Rick wants to give his legacy to Morty before bad guys catch them. There are n planets in their universe numbered from 1 to n.

一个神秘的oj2587 你猜是不是dp(线段树优化建图)

哇 这难道不是happiness的翻版题嘛? 从\(S\)向一个点连染成白色的收益 从这个点向\(T\)连染成黑色的收益 对于额外的收益,建一个辅助点,跟区间内的每个点连\(inf\),然后向S/T,连流量为收益 这不就结束了吗? 自信写完,提交 woc!!只有40分? #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath>

【题解】SDOI2010所驼门王的宝藏(强连通分量+优化建图)

[题解]SDOI2010所驼门王的宝藏(强连通分量+优化建图) 最开始我想写线段树优化建图的说,数据结构学傻了233 虽然矩阵很大,但是没什么用,真正有用的是那些关键点 考虑关键点的类型: 横走型 竖走型 八连通型 本质上只有两种类型(走一大串/走八连通),我们考虑这样一种建图方法: 对于每一行每一列建立一个点(点权为\(0\)) 对于关键点建立一个点(点权为\(1\)) 然后考虑这样一种建图方式,得到一个有点权无边权图 关键点所在的行与列无偿地向这个关键点连边 横走型的关键点向行连一条边,竖走