zoukankan      html  css  js  c++  java
  • HDU 4309 Seikimatsu Occult Tonneru (状压 + 网络流)

    题意:输入 n 个城市 m 条边,但是边有三种有向边 a b  c d,第一种是 d 是 0,那么就是一条普通的路,可以通过无穷多人,如果 d < 0,那么就是隧道,这个隧道是可以藏 c 个人,当然也是通过无穷多人的,如果 d > 0,那么这是一座桥,第一次可以通过一个人,如果修复的话,就可以通过无穷多人,问你最多藏的人数,还有最少花费。

    析:只是这样是不能做的,但是题目说了桥不超过 12 个,说实话这个条件太隐蔽了,就是不想让人发现,可惜的是队友没读出来,我也实在是没想出来怎么做,后来一查题解,知道有这个条件,那么很简单了,枚举桥的每一个状态,是修还是不修,每次跑一次最大流,进去判断,下面说一下怎么建图。

    建立一个超级源点 s 和超级汇点 t,对于每个城市,从 s 向每个城市连一条边,容量就是城市人数,然后对于普通的路,那么就直接连接容量无穷大,对于隧道也是直接连接容量无穷大,然后把隧道向汇点 t 连接,容量是可以藏人的数,注意连的隧道的左端点,最后是桥,每次枚举桥的状态,如果是修复,那么就连一条容量无穷大的,如果不修复,那么就连一条容量为 1 的边,然后就OK了。

    代码如下:

    #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 = 100 + 20;
    const int maxm = 1e6 + 10;
    const LL mod = 1000000000000000LL;
    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 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;
    }
    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);  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){
              d[e.to] = d[u] + 1;
              vis[e.to] = 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;
    
    struct Node{
      int u, v, c;
    };
    vector<Node> bridge;
    
    int main(){
      while(scanf("%d %d", &n, &m) == 2){
        int s = 0, t = n + 1;
        dinic.init(t + 5);
        bridge.cl;
        for(int i = 1; i <= n; ++i)  dinic.addEdge(s, i, readInt());
        bool ok = false;
        for(int i = 1; i <= m; ++i){
          int a, b, c, d;
          scanf("%d %d %d %d", &a, &b, &c, &d);
          if(d == 0)  dinic.addEdge(a, b, INF);
          else if(d < 0){
            dinic.addEdge(a, b, INF);
            dinic.addEdge(a, t, c);
            ok = true;
          }
          else  bridge.pb((Node){a, b, c});
        }
        if(!ok){ puts("Poor Heaven Empire");  continue; }
        int ans1 = 0, ans2 = 0;
        int all = 1<<bridge.sz;
        for(int i = 0; i < all; ++i){
          int tmp = 0;
          for(int j = 0; j < bridge.sz; ++j)
            if(i&1<<j){
              tmp += bridge[j].c;
              dinic.addEdge(bridge[j].u, bridge[j].v, INF);
            }
            else dinic.addEdge(bridge[j].u, bridge[j].v, 1);
          int res = dinic.maxFlow(s, t);
          if(res > ans1){
            ans1 = res;
            ans2 = tmp;
          }
          else if(res == ans1 && ans2 > tmp)  ans2 = tmp;
          for(int j = 0; j < bridge.sz; ++j){
            dinic.edges.pop_back();
            dinic.G[bridge[j].u].pop_back();
            dinic.G[bridge[j].v].pop_back();
          }
          for(int i = 0; i < dinic.edges.sz; ++i)
            dinic.edges[i].flow = 0;
        }
        if(ans1 == 0)  puts("Poor Heaven Empire");
        else  printf("%d %d
    ", ans1, ans2);
      }
      return 0;
    }
    

      

  • 相关阅读:
    如何在iTerm2中配置oh my zsh?
    sublime中格式化jsx文件
    ES6 new syntax of Literal
    ES6 new syntax of Rest and Spread Operators
    How to preview html file in our browser at sublime text?
    ES6 new syntax of Default Function Parameters
    ES6 new syntax of Arrow Function
    七牛云2018春招笔试题
    Spring-使用注解开发(十二)
    Spring-声明式事物(十一)
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/8972229.html
Copyright © 2011-2022 走看看