网络流

来源:互联网 发布:高分少女 知乎: 编辑:程序博客网 时间:2024/06/05 08:32
//网络流#include <stdio.h>#include <iostream>#include <string.h>#include <queue>const int N = 1005;int pre[N];       //保存增广路径上的点的前驱顶点bool vis[N];int map[N][N];    //残留网络容量int s, t;          //s为源点,t为汇点int n, m;bool BFS()        //找增广路{    int i, cur;    std::queue<int>Q;    memset(pre, 0, sizeof(pre));    memset(vis, 0, sizeof(vis));    vis[s] = true;    Q.push(s);    while (!Q.empty())    {        cur = Q.front();        Q.pop();        if (cur == t) return true;       //如果已达到汇点t,表明已经找到一条增广路径,返回true.        for (i = 1; i <= n; i++)        {            if (!vis[i] && map[cur][i])  //只有残留容量大于0时才存在边            {                Q.push(i);                pre[i] = cur;                vis[i] = true;            }        }    }    return false;}int Max_Flow(){    int i, ans = 0;    while (true)    {        if (!BFS()) return ans;     //如果找不到增广路径就返回。        int Min = 999999999;        for (i = t; i != s; i = pre[i])     //通过pre[]数组查找增广路径上的边,求出残留容量的最小值。            Min = std::min(Min, map[pre[i]][i]);        for (i = t; i != s; i = pre[i])        {            map[pre[i]][i] -= Min;            map[i][pre[i]] += Min;        }        ans += Min;    }}int main(){    int T, k = 1;    int u, v, c;    scanf("%d", &T);    while (T--)    {        scanf("%d%d", &n, &m);        s = 1; t = n;        memset(map, 0, sizeof(map));        while (m--)        {            scanf("%d%d%d", &u, &v, &c);            map[u][v] += c;        }        printf("Case %d: %d\n", k++, Max_Flow());    }    return 0;}
0 0
原创粉丝点击