您的位置:首页 > 其它

hdu4280 Island Transport 最大流模板Dinic算法

2015-08-24 10:15 344 查看
题意: 求从最左边的岛到最右边的岛的最大容量

这道题还学会了手动开栈

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#pragma comment(linker, "/STACK:1024000000,1024000000")//外挂开栈
using namespace std;
const int maxn = 100000 + 5;
const int inf = 0x7f7f7f7f;
int head[maxn], d[maxn];
int tot;
int n, m;
struct Eage{
    int t, w, next;
}eage[maxn*2];
inline void add(int x, int y, int c)
{
    eage[tot].t = y;
    eage[tot].w += c;
    eage[tot].next = head[x];
    head[x] = tot++;
    eage[tot].t = x;
    eage[tot].w += c;//注意这道题的边是双向的!
    eage[tot].next = head[y];
    head[y] = tot++;
}
bool bfs(int s, int t)
{
    queue<int> q;
    memset(d, -1, sizeof(d));
    d[s] = 0;
    q.push(s);

    while (!q.empty())
    {
        int u = q.front(); q.pop();
        if (u == t) return true;
        for (int i = head[u]; i != -1; i = eage[i].next)
        {
            int v = eage[i].t;
            if (d[v] == -1 && eage[i].w > 0)//i写成v调试两个多小时
            {
                d[v] = d[u] + 1;
                q.push(v);
            }
        }
    }
    return false;
}
int dfs(int u, int flow, int t)
{
    if (u == t) return flow;
    int sum = 0;
    for (int i = head[u]; i != -1; i = eage[i].next)
    {
        int v = eage[i].t;
        int w = eage[i].w;
        if (w > 0 && d[v] == d[u]+1) {
            int tmp = dfs(v, min(flow-sum, eage[i].w), t);
            eage[i].w -= tmp;
            eage[i^1].w += tmp;
            sum += tmp;
            if (sum == flow) return sum;
        }
    }
    if (sum == 0)d[u] = 0;
    return sum;
}

int dinic(int s, int t)
{
    int total = 0;
    while(bfs(s, t))
    {
        total+=dfs(s, inf, t);
    }
    return  total;
}

int main()
{
    //freopen("input.txt", "r", stdin);
    int t;
    cin >> t;
    while (t--)
    {
        cin >> n >> m;
        int s, t, x, y;
        int Min = inf, Max = -inf;
        for (int i = 1; i <= n; i++)
        {
            scanf("%d%d", &x, &y);
            if (x < Min) {
                Min = x;
                s = i;
            }
            if (x > Max)
            {
                Max = x;
                t = i;
            }
        }
        memset(head, -1, sizeof(head));
        memset(eage, 0, sizeof(eage));
        tot = 0;
        for (int i = 0; i < m; i++)
        {
            int u, v, x;
            scanf("%d%d%d", &u, &v, &x);
            add(u, v, x);
        }
        int ans = dinic(s, t);
        printf("%d\n", ans);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: