演算法步驟:
1. 先將原影象最大可行流那樣變換,唯一不同的是不加dst->src那條邊來將它變成無源無匯的網路流圖.直接跑一邊超級源到超級匯的最大流.
2. 加上剛才沒有加上的那條邊p
3. 再跑一遍超級源匯之間的最大流,p的流量就是我們要求的最小可行流流量(等於其反向邊的"容量")
收穫:1. 最大可行流和最小可行流,當我們把其殘量網路求出來後,其流量就是dst->src的殘量.
每條邊在此時的流量 = 流量下界 + 轉換後對應邊的流量
1 #include 2 #include 3 #include 4view code#define min(a,b) ((a)
5#define oo 0x3f3f3f3f
6#define n 110
7#define m n*n89
struct
dinic
18void adde( int i, int u, int v, int
f )
22bool
bfs() 34}
35}36return
dep[dst];37}
38int dfs( int u, int
a ) 50}
51return
past;52}
53int maxflow( int s, int
t )
60return
f;61}62
}dinic;
63struct
btop
72void adde( int i, int u, int v, int b, int
t )
78int minflow( int src, int
dst )
86 sum = 0;87
for( int u=1; u<=n; u++) else
if( sumo[u]>sumi[u] ) 94}
95int f = 0
;96 f +=dinic.maxflow(ss,tt);
97 dinic.adde( 0
, dst, src, oo );
98 f +=dinic.maxflow(ss,tt);
99if( f!=sum ) return -1
;100
int eid = dinic.etot-2
;101
return dinic.flow[eid^1
];102
}103
}btop;
104105
intn, m;
106int
ans[m], tot;
107108
intmain()
117int minf = btop.minflow(1
,n);
118if( minf==-1
) 122
for( int e=0; e)
126 printf( "
%d\n
", minf );
127for( int i=1; i<=m; i++)
128 printf( "
%d "
, ans[i] );
129 printf( "\n"
);130 }
sgu176 有源匯上下界最小流
題意 有一堆點和邊,1起點,n終點,某些邊有可能必須滿流,要求滿足條件的最小流 解法 按原圖建邊,滿流的即上下界都是容量,但是這樣按有源匯上下界可行流求出來的可能不是最小流,那麼我們需要開始建邊的時候不要建從t到s的邊,先跑一邊從ss到tt的最大流,然後把該邊加上再跑一次從ss到tt的最大流,那麼從...
上下界網路流初探
看文章各種不明真相.請教了一下iwtwiioi大牛.大致有個理解.建模過程 1.拆邊.對於每一條給出的有向邊 u,v,c,d 其中c指下界,d指上界,那麼在實際的圖中連三條只有上界沒有下界的邊 s,v,c u,t,c u,v,d c 其中s是超級源,t是超級匯.不同於題目給出的源與匯 一條是超級源連...
上下界網路流專題
給定n點m邊無向圖,用k個人從起點出發,乙個人走一條路代價為路的長度li,你希望按照0,1,2,n的順序依次經過這些點,其中經過的定義是任何1人經過該點,問k個人最小的道路總和。n 150,m 20 000,1 k 10,li 10 000 考慮每次只有1個人走1步,已經過t點,則每次其中一人走向t...