• AC_Dream 1211 Reactor Cooling


      1 /*
      2     题意:无源无汇,并且每条边的容量有上下界限的网络流问题!既然无源无汇,那么素有的节点都应该满足“入流==出流”!
      3          输出每一条边的流量,使得满足上面的条件。(如果u->v有流量,那么v->u就不会有流量)
      4 
      5     思路:如果增加了源点s和汇点t,对于u->v(下限为l, 上限为f) 将这一条边拆成3条,s->v(容量为l), u->v(容量为f-l)
      6      u->t(容量为l)这样就变成了每一个点的流入或者流出的流量至少是b!然后从s->t走一遍最大流,如果所有的附件边都已经
      7      满载,则就是所有s->v的边和u->t的边(或者只判断其中一者就可以),那么就存在答案!
      8 */
      9 #include<iostream>
     10 #include<cstdio>
     11 #include<cstring>
     12 #include<algorithm>
     13 #include<vector>
     14 #include<queue>
     15 #define INF 0x3f3f3f3f
     16 #define N 205
     17 #define M 500000
     18 using namespace std;
     19 
     20 struct EDGE{
     21     int v, cap, tot, nt, b;
     22     EDGE(){};
     23     EDGE(int v, int cap, int nt, int b) : v(v), cap(cap), nt(nt), b(b), tot(cap){}
     24 };
     25 
     26 EDGE edge[M];
     27 int n, m;
     28 int first[N];
     29 int pre[N], d[N];
     30 int sz;
     31 int s, t;
     32 int full, fout; 
     33 
     34 void addEdge(int u, int v, int b, int cap){
     35     edge[sz] = (EDGE(v, cap, first[u],b));
     36     first[u] = sz++;
     37     edge[sz] = (EDGE(u, 0, first[v], 0));
     38     first[v] = sz++;
     39 
     40     edge[sz] = (EDGE(v, b, first[s], 0));
     41     first[s] = sz++;
     42     edge[sz] = (EDGE(s, 0, first[v], 0));
     43     first[v] = sz++;
     44 
     45     edge[sz] = (EDGE(t, b, first[u], 0));
     46     full += b;
     47     first[u] = sz++;
     48     edge[sz] = (EDGE(u, 0, first[t], 0));
     49     first[t] = sz++;
     50 }
     51 
     52 bool bfs(){
     53     queue<int>q;
     54     memset(d, 0, sizeof(d));
     55     d[s] = 1;
     56     q.push(s);
     57     while(!q.empty()){
     58         int u = q.front(); q.pop();
     59         for(int i = first[u]; ~i; i = edge[i].nt){
     60             int v = edge[i].v;
     61             if(!d[v] && edge[i].cap >0){
     62                 d[v] = d[u] + 1;
     63                 q.push(v);
     64             }
     65         }
     66     }
     67     if(d[t] == 0) return false;
     68     return true;
     69 }
     70 
     71 int dfs(int u, int totf){
     72     int ff;
     73     if( u == t) return totf;
     74     int flow = 0;
     75     for(int i = first[u]; ~i && totf > flow; i = edge[i].nt){
     76         int v = edge[i].v;
     77         int cap = edge[i].cap;
     78         //流入u节点的当前总的流量为totf,可以得到 u->v1, u->v2, u->v3....这些路径上的最大流的和为flow+=f(u->vi)
     79         //f(u->vi)表示u节点沿着vi节点方向的路径上的最大流;如果u->vi+1的容量为wi+1,那么u->vi+1所允许流过的最大
     80         //的流量就是 min(totf - cost, wi+1)了!
     81         if(d[v] == d[u] + 1 && cap > 0 ){
     82             ff = dfs(v, min(totf - flow, cap));
     83             if(ff){
     84                 edge[i].cap -= ff;
     85                 edge[i^1].cap += ff;
     86                 flow += ff;
     87             }
     88             else
     89                 d[v] = -1;//表示v这个点无法在继续增广下去了
     90         }
     91     }
     92     return flow;//返回从u节点向外流出的最大流量!
     93 }
     94 
     95 bool Dinic(){
     96     while(bfs())
     97         fout += dfs(0, INF);//这一块没想到写成while(dfs())会超时....
     98 
     99     if( fout != full) return false;
    100     return true;
    101 }
    102 
    103 int main(){
    104      
    105         scanf("%d%d", &n, &m);
    106     memset(first, -1, sizeof(first));
    107     sz = 0;
    108     fout = full = 0;
    109     s = 0; t = n+1;
    110     int u, v, l, f;
    111     for(int i = 1; i <= m; ++i){
    112         scanf("%d%d%d%d", &u, &v, &l, &f);
    113         addEdge(u, v, l, f-l);
    114     }
    115     if(!Dinic()){
    116         printf("NO
    ");
    117         return 0;
    118     }
    119     printf("YES
    ");
    120     for(int i = 1; i <= m; ++i){
    121         int j = (i-1)*6;
    122         printf("%d
    ",  edge[j].tot - edge[j].cap + edge[j].b);//输出这条边实际流过的流量+下限
    123     }
    124 
    125     return 0;
    126 }
  • 相关阅读:
    每日站立会议08
    MAVEN常用命令
    android开发环境搭建
    阻止默认事件和阻止事件冒泡
    C#ActiveX安装项目
    System&Software
    poj 1386 Play on Words 有向欧拉回路
    poj 1033
    120.Triangle
    pandas中 transform 函数和 apply 函数的区别
  • 原文地址:https://www.cnblogs.com/hujunzheng/p/4006435.html
Copyright © 2020-2023  润新知