zoukankan      html  css  js  c++  java
  • UVaLive 4597 Inspection (网络流,最小流)

    题意:给出一张有向图,每次你可以从图中的任意一点出发,经过若干条边后停止,然后问你最少走几次可以将图中的每条边都走过至少一次,并且要输出方案,这个转化为网络流的话,就相当于 求一个最小流,并且存在下界,即每条边至少走一次。

    析:转载:http://blog.csdn.net/sdj222555/article/details/40380423

    这上面说的很清楚了,就是先求一遍是正向的,然后再求逆向的,这个逆向就是为了求可以减少的边。

    代码如下:

    #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 = 100 + 40;
    const int maxm = (100000 << 8) + 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(i, 0, n)  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;
    
    int in[maxn];
    vector<P>  edges[maxn];
    int main(){
      while(scanf("%d", &n) == 1){
        ms(in, 0);
        int s = 0, t = n + 1;
        dinic.init(t + 4);
        int ans = 0;
        for(int i = 1; i <= n; ++i){
          int x;  scanf("%d", &x);
          while(x--){
            int y;  scanf("%d", &y);
            ++in[y];  --in[i];
            dinic.addEdge(i, y, INF);
          }
          edges[i].cl;
        }
        int sum = 0;
        for(int i = 1; i <= n; ++i)
          if(in[i] > 0)  dinic.addEdge(s, i, in[i]), ans += in[i];
          else  dinic.addEdge(i, t, -in[i]);
        printf("%d
    ", ans -= dinic.maxflow(s, t));
        for(int i = 1; i <= n; ++i){
          for(int j = 0; j < dinic.G[i].sz; ++j){
            Edge &e = dinic.edges[dinic.G[i][j]];
            if(e.from != i || e.to == t || e.cap == 0)  continue;
            edges[i].pb(P(e.to, e.flow + 1));
            in[e.to] += e.flow;
          }
        }
        for(int i = 1; i <= n; ++i)  while(in[i] < 0){
          ++in[i];
          vector<int> ans;  ans.push_back(i);
          int u = i;
          while(1){
            bool ok = true;
            for(int j = 0; j < edges[u].sz; ++j){
              if(edges[u][j].se == 0)  continue;
              ok = false;
              --edges[u][j].se;
              u = edges[u][j].fi;
              ans.push_back(u);
              break;
            }
            if(ok)   break;
          }
          for(auto &it : ans)  printf("%d%c", it, " 
    "[it == ans.back()]);
        }
      }
      return 0;
    }
    

      

  • 相关阅读:
    IntelliJ IDEA 14.03 java 中文文本处理中的编码格式设置
    应聘感悟
    STL string分析
    CUDA SDK VolumeRender 分析 (1)
    BSP
    CUDA SDK VolumeRender 分析 (3)
    CUDA SDK VolumeRender 分析 (2)
    Windows软件发布时遇到的一些问题
    Ten Commandments of Egoless Programming (转载)
    复习下光照知识
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/7780903.html
Copyright © 2011-2022 走看看