zoukankan      html  css  js  c++  java
  • ZOJ2314 Reactor Cooling

    传送门

    题目大意:给定N(N<=200)个节点和M(范围未知)个管子。每个管子有一个流量的上限和下限(<=100000),求是否能在网络中形成可行流。如果能的话,还要输出每条管子中的流量。

    上下界网络流之可行流……这个就是比较基本的模板了。我们统计一下从每个点流入,流出的下限,之后建立辅助原点和辅助汇点,然后对于每个点,用流出下限减去流入下限,如果大于0就向辅助汇点连接容量为差值的边。否则向辅助源点连接容量为差值的绝对值的边。原图中每一条边的容量取上届减去下届的差值。

    之后图建好了,直接从辅助源点到辅助汇点跑最大流,判断这个最大流是否与从原点流出的流量相等。如果相等就说明有可行流,否则没有。

    这样就结束了,注意在复制head数组的时候不要复制少了。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<set>
    #include<vector>
    #include<map>
    #include<queue>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    #define fr friend inline
    #define y1 poj
    #define mp make_pair
    #define pr pair<int,int>
    #define fi first
    #define sc second
    #define pb push_back
    
    using namespace std;
    typedef long long ll;
    const int M = 100005;
    const int N = 205;
    const int INF = 1000000009;
    const double eps = 1e-7;
    
    int read()
    {
       int ans = 0,op = 1;char ch = getchar();
       while(ch < '0' || ch > '9') {if(ch == '-') op = -1;ch = getchar();}
       while(ch >= '0' && ch <= '9') ans = ans * 10 + ch - '0',ch = getchar();
       return ans * op;
    }
    
    struct edge
    {
       int next,to,from,v;
    }e[M<<1];
    
    int Ti,n,m,head[N<<1],ecnt,x,y,a[M<<1],b[M<<1],rsum[N<<1],csum[N<<1],S,T,tot,dep[N<<1],cur[N<<1];
    queue <int> q;
    
    void add(int x,int y,int z)
    {
       e[++ecnt].to = y;
       e[ecnt].next = head[x];
       e[ecnt].v = z;
       head[x] = ecnt;
    }
    
    void clear()
    {
       memset(head,-1,sizeof(head)),ecnt = -1,tot = 0;
       rep(i,S,T) rsum[i] = csum[i] = 0;
    }
    
    bool bfs(int s,int t)
    {
       while(!q.empty()) q.pop();
       rep(i,s,t) cur[i] = head[i];
       memset(dep,-1,sizeof(dep));
       dep[s] = 0,q.push(s);
       while(!q.empty())
       {
          int k = q.front();q.pop();
          for(int i = head[k];~i;i = e[i].next)
          {
    	 if(e[i].v && dep[e[i].to] == -1)
    	    dep[e[i].to] = dep[k] + 1,q.push(e[i].to);
          }
       }
       return dep[t] != -1;
    }
    
    int dfs(int s,int t,int lim)
    {
       if(s == t || !lim) return lim;
       int flow = 0;
       for(int i = cur[s];~i;i = e[i].next)
       {
          cur[s] = i;
          if(dep[e[i].to] != dep[s] + 1) continue;
          int f = dfs(e[i].to,t,min(lim,e[i].v));
          if(f)
          {
    	 e[i].v -= f,e[i^1].v += f;
    	 flow += f,lim -= f;
    	 if(!lim) break;
          }
       }
       if(!flow) dep[s] = -1;
       return flow;
    }
    
    int dinic(int s,int t)
    {
       int maxflow = 0;
       while(bfs(s,t)) maxflow += dfs(s,t,INF);
       return maxflow;
    }
    
    int main()
    {
       Ti = read();
       while(Ti--)
       {
          n = read(),m = read(),T = n + 1;
          clear();
          rep(i,0,m-1)
          {
    	 x = read(),y = read(),a[i] = read(),b[i] = read(),add(x,y,b[i]-a[i]),add(y,x,0);
    	 rsum[y] += a[i],csum[x] += a[i];
          }
          rep(i,1,n)
          {
    	 int now = csum[i] - rsum[i];
    	 if(now < 0) add(S,i,-now),add(i,S,0);
    	 else add(i,T,now),add(T,i,0),tot += now;
          }
          if(tot != dinic(S,T)) printf("NO
    ");
          else
          {
    	 printf("YES
    ");
    	 rep(i,0,m-1) printf("%d
    ",e[i<<1|1].v + a[i]);
          }
       }
       return 0;
    }
    
    
  • 相关阅读:
    java中bean和xml相互转换
    java操作zip文件
    java内置的解压缩工具
    java操作Excel简单入门
    java开发IDEA插件入门
    java中Class.getResourceAsStream()和ClassLoader.getResourceAsStream()的区别
    java中文转拼音
    vue父子组件通信
    学会使用box-sizing布局
    webpack-dev-server 导致的 invalid host header
  • 原文地址:https://www.cnblogs.com/captain1/p/10134773.html
Copyright © 2011-2022 走看看