LightOJ 1153 - Internet Bandwidth【最大流】

来源:互联网 发布:超牛数据恢复手机版 编辑:程序博客网 时间:2024/06/06 04:09

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1153

注意自环

代码:

#include <iostream>  #include <algorithm>  #include <set>  #include <map>  #include <string.h>  #include <queue>  #include <sstream>  #include <stdio.h>  #include <math.h>  #include <stdlib.h>  using namespace std;const int MAXN = 10100;//点数的最大值const int MAXM = 4000100;//边数的最大值const int INF = 0x3f3f3f3f;struct Edge{    int to, next, cap, flow;}edge[MAXM];//注意是MAXMint tol;int head[MAXN];int gap[MAXN], dep[MAXN], pre[MAXN], cur[MAXN];void init(){    tol = 0;    memset(head, -1, sizeof(head));}//加边,单向图三个参数,双向图四个参数void addedge(int u, int v, int w, int rw = 0){    edge[tol].to = v; edge[tol].cap = w; edge[tol].next = head[u];    edge[tol].flow = 0; head[u] = tol++;    edge[tol].to = u; edge[tol].cap = rw; edge[tol].next = head[v];    edge[tol].flow = 0; head[v] = tol++;}//输入参数:起点、终点、点的总数//点的编号没有影响,只要输入点的总数int sap(int start, int end, int N){    memset(gap, 0, sizeof(gap));    memset(dep, 0, sizeof(dep));    memcpy(cur, head, sizeof(head));    int u = start;    pre[u] = -1;    gap[0] = N;    int ans = 0;    while (dep[start] < N)    {        if (u == end)        {            int Min = INF;            for (int i = pre[u]; i != -1; i = pre[edge[i ^ 1].to])                if (Min > edge[i].cap - edge[i].flow)                    Min = edge[i].cap - edge[i].flow;            for (int i = pre[u]; i != -1; i = pre[edge[i ^ 1].to])            {                edge[i].flow += Min;                edge[i ^ 1].flow -= Min;            }            u = start;            ans += Min;            continue;        }        bool flag = false;        int v;        for (int i = cur[u]; i != -1; i = edge[i].next)        {            v = edge[i].to;            if (edge[i].cap - edge[i].flow && dep[v] + 1 == dep[u])            {                flag = true;                cur[u] = pre[v] = i;                break;            }        }        if (flag)        {            u = v;            continue;        }        int Min = N;        for (int i = head[u]; i != -1; i = edge[i].next)            if (edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)            {                Min = dep[edge[i].to];                cur[u] = i;            }        gap[dep[u]]--;        if (!gap[dep[u]])return ans;        dep[u] = Min + 1;        gap[dep[u]]++;        if (u != start) u = edge[pre[u] ^ 1].to;    }    return ans;}int m, n, s, t;int a, b, c;int main(){    int T, cases = 1;    scanf("%d", &T);    while (T--)    {        init();        scanf("%d", &n);        scanf("%d%d%d", &s, &t, &m);        while (m--)        {            scanf("%d%d%d", &a, &b, &c);            if (a != b)            {                addedge(a, b, c, c);            }        }        int ans = sap(s, t, n);        printf("Case %d: %d\n", cases++, ans);    }    return 0;}
0 0
原创粉丝点击