sgu 194 上下界网络流可行流判定+输出可行流

  1 #include <cstdio>
  2 #include <cstring>
  3 #define min(a,b) ((a)<(b)?(a):(b))
  4 #define oo 0x3f3f3f3f
  5 #define N 210
  6 #define M 100010
  7
  8 struct Dinic {
  9     int n, src, dst;
 10     int head[N], dest[M], flow[M], eid[M], next[M], etot;
 11     int cur[N], dep[N], qu[N], bg, ed;
 12
 13     void init( int n, int src, int dst ) {
 14         this->n = n;
 15         this->src = src;
 16         this->dst = dst;
 17         etot = 0;
 18         memset( head, -1, sizeof(head) );
 19     }
 20     void adde( int id, int u, int v, int f ) {
 21         next[etot]=head[u], flow[etot]=f, dest[etot]=v, eid[etot]=id; head[u]=etot++;
 22         next[etot]=head[v], flow[etot]=0, dest[etot]=u, eid[etot]=-1; head[v]=etot++;
 23     }
 24     bool bfs() {
 25         memset( dep, 0, sizeof(dep) );
 26         qu[bg=ed=1] = src;
 27         dep[src] = 1;
 28         while( bg<=ed ) {
 29             int u=qu[bg++];
 30             for( int t=head[u]; ~t; t=next[t] ) {
 31                 int v=dest[t], f=flow[t];
 32                 if( f && !dep[v] ) {
 33                     dep[v] = dep[u]+1;
 34                     qu[++ed] = v;
 35                 }
 36             }
 37         }
 38         return dep[dst];
 39     }
 40     int dfs( int u, int a ) {
 41         if( u==dst || a==0 ) return a;
 42         int remain=a, past=0, na;
 43         for( int &t=cur[u]; ~t; t=next[t] ) {
 44             int v=dest[t], &f=flow[t], &vf=flow[t^1];
 45             if( f && dep[v]==dep[u]+1 && (na=dfs(v,min(remain,f))) ) {
 46                 f -= na;
 47                 vf += na;
 48                 remain -= na;
 49                 past += na;
 50                 if( !remain ) break;
 51             }
 52         }
 53         return past;
 54     }
 55     int maxflow() {
 56         int f = 0;
 57         while( bfs() ) {
 58             for( int u=1; u<=n; u++ ) cur[u]=head[u];
 59             f += dfs(src,oo);
 60         }
 61         return f;
 62     }
 63     void print( int *ans ) {
 64         for( int e=0; e<etot; e++ )
 65             if( eid[e]!=-1 ) ans[eid[e]]+=flow[e^1];
 66     }
 67 }D;
 68 struct Bottop {
 69     int n;
 70     int head[N], dest[M], bot[M], top[M], next[M], eid[M], etot;
 71     int si[N], so[N], sum;
 72
 73     void init( int n ) {
 74         this->n = n;
 75         memset( head, -1, sizeof(head) );
 76         memset( si, 0, sizeof(si) );
 77         memset( so, 0, sizeof(so) );
 78         etot = 0;
 79     }
 80     void adde( int id, int u, int v, int b, int t ) {
 81         eid[etot]=id, next[etot]=head[u], bot[etot]=b, top[etot]=t, dest[etot]=v;
 82         head[u]=etot++;
 83     }
 84     void build( int *ans ) {
 85         int src=n+1, dst=n+2;
 86         D.init( dst, src, dst );
 87         for( int u=1; u<=n; u++ )
 88             for( int t=head[u]; ~t; t=next[t] ) {
 89                 int v=dest[t];
 90                 ans[eid[t]] += bot[t];
 91                 si[v] += bot[t];
 92                 so[u] += bot[t];
 93                 D.adde( eid[t], u, v, top[t]-bot[t] );
 94             }
 95         for( int u=1; u<=n; u++ ) {
 96             if( so[u]>si[u] )
 97                 D.adde( -1, u, dst, so[u]-si[u] );
 98             else if( si[u]>so[u] ) {
 99                 D.adde( -1, src, u, si[u]-so[u] );
100                 sum += si[u]-so[u];
101             }
102         }
103     }
104     bool ok() { return D.maxflow()==sum; }
105 }B;
106
107 int n, m;
108 int ans[M];
109
110 int main() {
111     scanf( "%d%d", &n, &m );
112     B.init(n);
113     for( int i=1,u,v,b,t; i<=m; i++ ) {
114         scanf( "%d%d%d%d", &u, &v, &b, &t );
115         B.adde( i, u, v, b, t );
116     }
117     B.build(ans);
118     bool ok = B.ok();
119     printf( "%s\n", ok ? "YES" : "NO" );
120     if( ok ) {
121         D.print( ans );
122         for( int i=1; i<=m; i++ )
123             printf( "%d\n", ans[i] );
124     }
125 }

时间: 2024-10-15 21:47:45

sgu 194 上下界网络流可行流判定+输出可行流的相关文章

sgu 194上下界网络流

又搞了个模板,这个模板应该ok,足以应付各种网络流了 题意:给n个点m 条边,其中每条边的流量有两个限制不能大于r不能小于l,求是否有可行解,如有输出每条边的流量 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn = 1000000; const int oo = 0x3777777; st

sgu 176 上下界网络流最小可行流带输出方案

算法步骤: 1. 先将原图像最大可行流那样变换,唯一不同的是不加dst->src那条边来将它变成无源无汇的网络流图.直接跑一边超级源到超级汇的最大流. 2. 加上刚才没有加上的那条边p 3. 再跑一遍超级源汇之间的最大流,p的流量就是我们要求的最小可行流流量(等于其反向边的"容量") 收获: 1. 最大可行流和最小可行流,当我们把其残量网络求出来后,其流量就是dst->src的残量. 每条边在此时的流量 = 流量下界 + 转换后对应边的流量 1 #include <c

hdu 4940 Destroy Transportation system( 无源汇上下界网络流的可行流推断 )

题意:有n个点和m条有向边构成的网络.每条边有两个花费: d:毁坏这条边的花费 b:重建一条双向边的花费 寻找这样两个点集,使得点集s到点集t满足 毁坏全部S到T的路径的费用和 > 毁坏全部T到S的路径的费用和 + 重建这些T到S的双向路径的费用和. 思路1: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center&quo

hdu 4940 Destroy Transportation system( 无源汇上下界网络流的可行流判断 )

题意:有n个点和m条有向边构成的网络,每条边有两个花费: d:毁坏这条边的花费 b:重建一条双向边的花费 寻找这样两个点集,使得点集s到点集t满足 毁坏所有S到T的路径的费用和 > 毁坏所有T到S的路径的费用和 + 重建这些T到S的双向路径的费用和. 思路1: 然后这个无源汇带上下界网络流的可行流问题的求解方法见这里~~ 建图就是上面说的那样啦~最后判断有没有可行流就是求一下我们所构造的这个新的网络的最大流~然后判断一下这个最大流是否满流~(即判断最大流是否和附加源点的流出总量相等~~) cod

[BZOJ2502]清理雪道 有上下界网络流(最小流)

2502: 清理雪道 Time Limit: 10 Sec  Memory Limit: 128 MB Description 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向. 你的团队负责每周定时清理雪道.你们拥有一架直升飞机,每次飞行可以从总部带一个人降落到滑雪场的某个地点,然后再飞回总部.从降落的地点出发,这个人可以顺着斜坡向下滑行,并清理他所经过的雪道. 由于每次飞行的耗费是固定的,为了最小化耗费

@总结 - 8@ 上下界网络流等一类网络流问题

目录 @0 - 参考资料@ @1 - 问题引入@ @2 - 上下界可行流@ @3 - 上下界最大流/最小流@ @4 - 上下界费用流@ @5 - 带负环的最小费用流@ @6 - 例题与参考代码实现@ @7 - 一些类似的杂题@ @0 - 参考资料@ menci 的博客 liu_runda 的博客 @1 - 问题引入@ 我们知道,通常情况下,一个合法的流应该具有如下几个性质: (1)(除源点汇点以外)流量守恒:\(\sum f(i, u) = \sum f(u, j)\). (2)斜对称性:\(f

有上下界的网络流2-有源汇带上下界网络流ZOJ3229

ZOJ3229题目大意:一个屌丝给m个女神拍照,计划拍照n天,每一天屌丝可以和C个女神拍照,每天拍照数不能超过D张,而且给每个女神i拍照有数量限制[Li,Ri],对于每个女神n天的拍照总和不能少于Gi,如果有解求屌丝最多能拍多少张照,并求每天给对应女神拍多少张照:否则输出-1. 解题思路:        1.增设一源点st,汇点sd,st到第i天连一条上界为Di下界为0的边,每个女神到汇点连一条下界为Gi上界为正无穷的边,对于每一天,当天到第i个女孩连一条[Li,Ri]的边.        2.

SGU 194 Reactor Cooling ——网络流

[题目分析] 无源汇上下界可行流. 上下界网络流的问题可以参考这里.↓ http://www.cnblogs.com/kane0526/archive/2013/04/05/3001108.html [代码] #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> //#include <map> #include <set> #include

acdream 1211 Reactor Cooling 【上下界网络流 + 输出流量】

题目:acdream 1211 Reactor Cooling 分类:无源无汇的有上下界网络流. 题意: 给n个点,及m根pipe,每根pipe用来流躺液体的,单向的,每时每刻每根pipe流进来的物质要等于流出去的物质,要使得m条pipe组成一个循环体,里面流躺物质. 并且满足每根pipe一定的流量限制,范围为[Li,Ri].即要满足每时刻流进来的不能超过Ri(最大流问题),同时最小不能低于Li. 例如: 46(4个点,6个pipe) 12 1 3 (1->2上界为3,下界为1) 23 1 3