117 有源匯有上下界最小流

2021-08-28 17:21:17 字數 1812 閱讀 4996

題目描述

n nn 個點,m mm 條邊,每條邊 e ee 有乙個流量下界 lower(e) \text(e)lower(e) 和流量上界 upper(e) \text(e)upper(e),給定源點 s ss 與匯點 t tt,求源點到匯點的最小流。

輸入格式

第一行兩個正整數 n nn、m mm、s ss、t tt。

之後的 m mm 行,每行四個整數 s ss、t tt、lower \textlower、upper \textupper。

輸出格式

如果無解,輸出一行please go home to sleep

否則輸出最小流。

樣例樣例輸入

7 12 6 7

6 1 0 2147483647

1 7 0 2147483647

6 2 0 2147483647

2 7 0 2147483647

6 3 0 2147483647

3 7 0 2147483647

6 4 0 2147483647

4 7 0 2147483647

6 5 0 2147483647

5 7 0 2147483647

5 1 1 2147483647

3 4 1 2147483647

樣例輸出

2
資料範圍與提示

1≤n≤50003,1≤m≤125003 1 \leq n \leq 50003 , 1\leq m \leq 1250031≤n≤50003,1≤m≤125003

**:

#include using namespace std ;

#define copy( a , x ) memcpy ( a , x , sizeof a )

typedef long long ll ;

const int maxn = 115000 ;

const int maxe = 1000000 ;

const int maxq = 1000000 ;

const int inf = 0x3f3f3f3f ;

struct edge

} ;struct network

void addedge ( int u , int v , ll c , ll rc = 0 )

void rev_bfs () }}

ll isap ()

for ( i = cur[u] ; ~i ; i = edge[i].n )

if ( edge[i].c && d[u] == d[edge[i].v] + 1 )

break ;

if ( ~i )

else

}return flow ;

}} ;int read ()

return x ;

}network net ;

int pp;

int n,m,k;

ll to[maxn];

int ss,tt;

void work ()

ll sum=0;

for(int i=1;i<=n;i++)

else

} ll flow =net.isap();

net.addedge(tt,ss,inf);

flow += net.isap();

if(flow==sum)

puts("please go home to sleep");

}int main()

LOJ 117 有源匯有上下界最小流

我們看到有源點和匯點的上下界最小流,即在可行流的基礎上要求流量最小。我們先跑一遍可行流,設可行流為flow1flow1flow1 則最小流為可行流 還能向下浮動的流量flow2flow2flow2 其實我們可以發現還能向下浮動的流量就是從原圖匯點到原圖源點的最大流 感性理解 因此步驟為 跑出乙個有源...

有源匯有上下界的最小流(LOJ117)

其實最小流和最大流個人感覺很類似,連線了超級源點和超級匯點之後跑完一次最大流,乙個是再在除去超級源點和超級匯點跑一次最大流,乙個是給源匯點連乙個無限邊求最大流,然後無限邊的流量就是答案 因為乙個相當於是要把殘量網路剩下的流加起來,才是最大流,而這個跑過最大流後剩下的就是最小流了 好像是有點點問題的,...

有源匯有上下界最大 最小流

建圖還是要想一想的.寫一下吧 首先根據有源匯可行流建圖,正向附加邊滿流證明有可行流 然後在這個殘量網路上刪掉 t,s,oo 這條邊,跑 s t 最大流就是最大流,t s 最大流就是最小流 include define int long long define ll long long define ...