poj 1273 入门级最大流

很基本的最大流问题,注意重边就好……


自己写了个EK模板,重边部分没有处理好,WA了好几次。

hdu 1523也是一样的题目(不过忘记杭电用I64d,poj用lld这个问题了……于是TLE了好几次……)


/****
裸最大流问题
EK算法
1004K	0MS	C++	3768B	2012-10-18 16:13:15
Ps:一开始Max = 1000 flow、lim数组开了long long的时候时间是47MS=   =
ps:hdu 要用I64d......
****/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
#define Begin_s 1
using namespace std;
const int Max = 410;
int path[Max];
int flow[Max][Max];
int lim[Max];
bool vis_seg[Max][Max];
bool vis[Max];
int pre[Max];
void q_clear( std::queue<int> &q )
{
    std::queue<int> empty;
    std::swap( q, empty );
}
struct no
{
    int v;
    int next;
} note[Max];
inline void init()
{
    memset(vis , 0 ,sizeof(vis));
    memset(path , 0 , sizeof(path));
    memset(lim , 0 , sizeof(lim));
}
inline void Ford_Fulkerson(int n , int u0)/****Time:O(nmU) U:f(u,v)****/
{
    bool note_break = true;
    queue<int> Q;
    while(note_break)
    {
        //update flow
        int tem = n;
        int add = lim[n];
        while(tem != u0 && tem != 0 && lim[tem])
        {
            int add2 = (flow[path[tem]][tem] >= 0 ? -add : add);
            flow[path[tem]][tem] += add2;
            flow[tem][path[tem]] += add2;
            tem = path[tem];
        }
        //initialize
        init();
        q_clear(Q);
        path[u0] = u0;
        lim[u0] = 2e8;
        vis[u0] = 1;
        Q.push(u0);
        //bfs
        while(!lim[n])
        {
            if(Q.empty() && !lim[n])
            {
                note_break = false;
                break;
            }
            int u = Q.front();
            Q.pop();
            int p = pre[u];
            while(p)
            {
                if(vis[note[p].v])
                {
                    p = note[p].next;
                    continue;
                }
                if(flow[u][note[p].v] >=0)
                    lim[note[p].v] = min(lim[u] , flow[u][note[p].v]);
                else
                    lim[note[p].v] = min(lim[u] , -flow[u][note[p].v]);
                if(lim[note[p].v])
                {
                    path[note[p].v] = u;
                    Q.push(note[p].v);
                    vis[note[p].v] = 1;
                }
                p = note[p].next;
            }
        }
    }
}
int main()
{
//    freopen("123.txt","r",stdin);
    int n , m;
    while(~scanf("%d %d" , &m , &n))
    {
        memset(note , -1 , sizeof(note));
        memset(pre  , 0 , sizeof(pre));
        memset(flow , 0 , sizeof(flow));
        memset(vis_seg , 0 , sizeof(vis_seg));
        init();
        //build the adjacency list
        int index = 1;
        for(int i = 1 ; i <= m ; i++)
        {
            int u , v , f;
            long long c;
            scanf("%d %d %d" , &u , &v , &c);
            if(u == n) continue;
            if(!vis_seg[u][v])
            {
                vis_seg[u][v] = vis_seg[v][u] = 1;
                note[index].v = v;
                note[index].next = pre[u];
                pre[u] = index++;

                note[index].v = u;
                note[index].next = pre[v];
                pre[v] = index++;
            }
            flow[u][v] += c;
//            flow[v][u] = 0;
        }
        Ford_Fulkerson(n , Begin_s);
//        for(int i = Begin_s ; i <= n ; i++)
//        {
//            int p = pre[i];
//            while(p)
//            {
//                if(flow[i][note[p].v] != 0)
//                    printf("%d -> %d: f:%d\n" , i , note[p].v , flow[i][note[p].v]);
//                p = note[p].next;
//            }
//        }
        long long Max_flow = 0;
        int p = pre[n];
        while(p)
        {
            Max_flow += (-flow[n][note[p].v]);
            p = note[p].next;
        }
        printf("%lld\n" , Max_flow);
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值