網路流高階

2022-05-07 10:00:12 字數 3319 閱讀 7587

先把三道例題扔在這裡吧qvq

無源匯有上下界可行流

有源匯有上下界最大流

有源匯有上下界最小流

首先預設把下界跑滿 但顯然這樣是不滿足流量平衡的

所以建立超級源s,超級匯t

把所有「入不敷出」的點向t連一條大小為 出流-入流 的邊

把s向所有入流大的點連一條大小為 入流-出流 的邊

此時跑一遍網路流 如果與s相連的邊都滿流了 那麼t也滿流了

整個圖即可行 否則不可行

#include #include #include #include #include using namespace std;

const int n = 205;

const int m = 1e6;

const int inf = 0x3f3f3f3f;

struct edgeedge[m];

int head[n], cur[n], esize = -1;

inline void addedge(int x, int y, int z);

head[x] = esize;

edge[++esize] = (edge);

head[y] = esize;

}int n, m, s, t, cnt, mf;

int low[m], upp[m], in[n], out[n];

int dis[n], fro;

queueque;

bool bfs()

} }return dis[t];

}int dfs(int x, int rest)

} }return 0;

}void dinic()

} int main()

s = n + 1, t = n + 2;

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

else if(out[i] > in[i]) addedge(i, t, out[i] - in[i]);

} dinic();

if(mf == cnt)

} else printf("no\n");

return 0;

}

在原圖上再跑一次最大流就好啦

#include #include #include #include #include using namespace std;

const int n = 205;

const int m = 1e6;

const int inf = 0x3f3f3f3f;

struct edgeedge[m];

int head[n], cur[n], esize = -1;

inline void addedge(int x, int y, int z);

head[x] = esize;

edge[++esize] = (edge);

head[y] = esize;

}int n, m, s, t, ss, tt, cnt, mf;

int low[m], upp[m], d[n];

int dis[n], fro;

queueque;

bool bfs(int s, int t)

} }//printf("%d\n", dis[t]);

return dis[t];

}int dfs(int x, int rest, int t)

} }return 0;

}void dinic(int s, int t)

} int main()

//printf("*");

ss = n + 1, tt = n + 2;

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

else if(d[i] < 0) addedge(i, tt, -d[i]);

} addedge(t, s, inf);

int rec = esize;

dinic(ss, tt);

if(mf != cnt)

head[s] = edge[head[s]].next;

head[t] = edge[head[t]].next;

dinic(s, t); mf += edge[rec].f;

printf("%d", mf);

return 0;

}

1.從ss到tt跑最大流

2.從t到s連一條大小為inf的邊

3.從ss到tt跑最大流

4.最後t到s的流量就是最小流

#include #include #include #include #include using namespace std;

const int n = 5e4 + 9;

const int m = 1e6;

const int inf = 0x3f3f3f3f;

struct edgeedge[m];

int head[n], cur[n], esize = -1;

inline void addedge(int x, int y, int z);

head[x] = esize;

edge[++esize] = (edge);

head[y] = esize;

}int n, m, s, t, ss, tt, cnt, mf;

int low[m], upp[m], d[n];

int dis[n], fro;

queueque;

bool bfs(int s, int t)

} }//printf("%d\n", dis[t]);

return dis[t];

}int dfs(int x, int rest, int t)

} return tmp;

}void dinic(int s, int t)

} int main()

//printf("*");

ss = n + 1, tt = n + 2;

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

else if(d[i] < 0) addedge(i, tt, -d[i]); }

dinic(ss, tt);

addedge(t, s, inf);

int rec = esize;

dinic(ss, tt);

if(mf != cnt)

else printf("%d", edge[rec].f);

return 0;

}

網路流 費用流

這個好像不考 沒事可以騙分 費用流,顧名思義,就是有費用的流,也就是說,給乙個網路流圖中的每條弧增加乙個單位流量費用。一般來說求解的費用流都是最大流最小費用。好像沒什麼好bb的 這裡推薦使用zkw演算法求解最小費用流,看著 理解就行,應該還是很好理解的。zkw演算法在稠密圖上跑得飛快,在稀疏圖上還不...

網路流 費用流

網路流有很多種類 其中最大流 有增廣路演算法和預流推進演算法。增廣路演算法就是不斷的新增增廣路。其中的dinic演算法。會稍微提到isap演算法 poj1273 首先想到dfs一直往後延伸,然後從源點到匯點計算每條路,但是這樣只是單條路的最值,有時可能因為走一條路而間接的認定了除這條路以外的某個路通...

中學高階本 網路流24題 餐巾計畫

把每天分為二分圖兩個集合中的頂點 xi,yi 建立附加源s匯 t。1 從s 向每個xi 連一條容量為 ri,費用為 0的有向邊。表示第 天還剩 條餐巾。2 從每個yi向 t連一條容量為 ri,費用為 0的有向邊。控制最大流 3 從s 向每個yi 連一條容量為無窮大,費用為 p的有向邊。表示買餐巾 4...