網路流問題在已經知道每條邊的容量以及流量的情況下,求出從起點到終點可以運送的最大流量。
這裡面需要注意的有:容量限制,斜對稱性和流量平衡的3個條件。
容量限制即保證每個邊流過的流量小於每個邊的容量 ,即f(u,v) < c(u,v);
斜對稱性即為:f(u,v) = -f(v,u);
流量平衡即為:除了起點和終點外每個點都需要流進的流量等於流出的流量,同時起點流出的流量要等於終點流入的流量。
我們在解決問題的時候,用到的增廣路演算法就是需要不斷地增加流量,知道無法增加流量為止。
同時需要構建乙個殘餘網路圖,這在下面的**中我會介紹。
增光路演算法基於乙個事實:殘餘網路任何一條從s到t的有向道路都對應原圖中的一條增廣路———只要求出該道路中所有所有殘量的最小值d,
把對應的所有邊的流量增加d即可,這個過程稱為增廣。
增廣前的流量滿足我所介紹的3個條件,很顯然我們增廣後的流量仍然滿足以上的3個條件。
這裡我介紹一下增廣路定理:如果殘餘網路不存在增廣路,則當前流就是最大流。
因為要找任意路徑,做一簡單的方法就是dfs,但是有時候會很慢。對於杭電1532 drainage ditches這道模板題我首先給出dfs方法
#include #include #include #include #include using namespace std;
const int n = 205;
const int inf = 0x3f3f3f3f;
struct node
;vector v[n];
bool used[n];
void add_node(int from,int to,int cap)
); v[to].push_back((node)); //因為已經放進去了所以要減一。
}int dfs(int s,int t,int f)}}
return 0; // 這一定不能省略,因為有可能找不到增廣路,這時候就要返回0了。
}int max_flow(int s,int t)
}int main()
printf("%d\n",max_flow(1,m));
}return 0;
}
還有一種方法就是bfs方法,這個演算法可以對付一些不是很刁鑽的網路流題目,這就是edmonds-karp演算法,這裡我同樣以剛才的題目貼出bfs演算法。
#include #include #include #include #include #include using namespace std;
const int maxn = 205;
const int inf = 0x3f3f3f3f;
struct edge
};struct ek
void addedge(int from, int to, int cap)
int maxflow(int s,int t)
}if(a[t]) break;
}if(!a[t]) break;
for(int u = t; u != s; u = edges[p[u]].from)
flow += a[t];
}return flow;
}}result;
int main()
printf("%d\n",result.maxflow(1,n));
}return 0;
}
hdu1532 網路流最大流問題
這是我的網路流第一題,用的是增廣路演算法即ek演算法,演算法思想 每次用bfs找一條最短的增廣路徑,然後沿著這條路徑修改流量值 實際修改的是殘量網路的邊權 順帶修改反圖的殘餘網路的邊權。當沒有增廣路時,演算法停止,此時的流就是最大流。還有這裡之所以要建反圖是因為,bfs找最短的增廣路的時候是隨機找的...
hdu 1532最大流 增廣路
include include include includeusing namespace std define max 210 int flow max max int pre max mark max int n,m,f int q,z void maxliu if mark n 如果mark...
最大流模板題 HDU 1532
hdu 1532 題意 給你m條邊 但向邊 n個點,n個點的編號為1到n,問從1到n的最大流是多少。最大流模板題,聽說有重邊,但是沒管重邊這個事也過了。dinic演算法 include define mem a,b memset a b,sizeof a define de coutvoid add...