來自loj的模板題
我們可以依照以下幾個步驟來解決這個問題。
1.讓所有的邊都流下界數量的水
2.計算每個點流入的水量−
-−流出的水量d[x
]d[x]
d[x]
3.建超級源點s
ss和超級匯點t
tt4.對於每個點,若d[x
]>
0d[x]>0
d[x]
>
0則連邊s,x
,d[x
]s,
x,d[
x],如果d[x
]<
0d[x]<0
d[x]
<
0,則連邊x,t
,−d[
x]
x,t,−d
[x]5.按原圖建邊,對於每條邊,建權值為上界−
-−下界的邊
6.跑最大流
7.如果s
ss點連出的邊中,有一條最終的權值不為0
00,那麼該圖不存在可行流
8.原圖的邊在新圖中反向邊上的流量就是這條邊需要再加上的流量
也就是說這條邊的總流量=
==下界流量+
++新圖中反向邊的流量
這個怎麼證明呢?
因為我們初始的操作已經滿足了下界的要求,而我們連邊的權值保證了不會超過上界。所以我們只要保證流量平衡即可。
這裡可以感性的理解,由於最後的圖中從s
ss出發的所有邊最終流量都為0
00,也就是原來d[x
]>
0d[x]>0
d[x]
>
0的點加上新圖的流量後已經處於流量平衡的狀態。那麼顯然此時d[x
]<
0d[x]<0
d[x]
<
0的點也都處於流量平衡狀態(因為顯然∑d[
x](d
[x
]>0)
=∑−d
[x](
d[x]
<0)
\sum=\sum
∑d[x](
d[x]
>0)
=∑−d
[x](
d[x]
<0)
)。所以這種狀態就是一種可行流。
**:
#include#define maxn 30005
using namespace std;
int read()
int n,m,s,t,cnt,d[maxn],l[maxn],u[maxn],x[maxn],y[maxn];
int head[maxn],nxt[maxn],ori[maxn],dis[maxn];
struct nodel[maxn];
void add(int x,int y,int c,int id);
nxt[cnt]=head[x];head[x]=cnt;cnt++;
l[cnt]=(node);
nxt[cnt]=head[y];head[y]=cnt;cnt++;
}queueq;
int bfs()
} }return dis[t];
}int dfs(int x,int now)
} if(!res) dis[x]=-1;
return res;
}int main()
for(int i=1;i<=n;i++)
for(int i=1;i<=m;i++)
while(bfs()) dfs(s,2e9);
for(int i=head[s];i!=-1;i=nxt[i])
} puts("yes");
for(int i=0;ifor(int i=1;i<=m;i++) printf("%d\n",ori[i]);
return 0;
}
無源匯有上下界可行流 loj模板
loj模板題 思想是 如果存 在可行流 每條邊 必定至少 有下界的 流量 思想是,如果存在可行流,每條邊必定至少有下界的流量 思想是,如果 存在可行 流,每條 邊必定至 少有下界 的流量 那 麼直 接用下屆 填充邊的 流量 那麼直接用下屆填充邊的流量 那麼直接用下 屆填充邊 的流量 每 條邊 的流量...
loj 115 無源匯有上下界可行流
參考部落格 模型 乙個網路,求出乙個流,使得每條邊的流量必須 li且 hi,每個點必須滿足總流入量 總流出量 流量守恆 這個流的特點是迴圈往復,無始無終 這個演算法是有上下界網路流演算法的基礎,只要深刻理解這個演算法其他演算法也就水到渠成,因此我用大篇幅力圖將這個演算法的思想和細節闡述清楚.可行流演...
LOJ 115 無源匯有上下界可行流
模板題 首先把下界去掉 連邊upper lower 然後記錄每個點至少要流出的和流入的流量 下界 然後流入大於流出的連向tt,流出大於流入的連向ss 補流 然後跑最大流,如果sum flow,就代表加上的邊滿流,有答案,否則沒有 include include include include inc...