hdu 4280 最大流isap

/*
题意:有N个岛屿和M条路线连接岛屿,这些路线可以在单位时间内运输一定数量的人数,给出每个岛屿的坐标,
问从最西的岛向最东的最大运输量是多少。

题解:赤果果的最大流;
邻接表建无向图,找出最东最西的岛屿并且求最大流。

注意:本题用了网上的ISAP模版,不知为何用sap模版疯狂的错误还是超时,反正是被坑了无敌久,当时也是对
两个模版都还不太熟,所以也没改好,也许sap也能过。
*/
#include <iostream>
#include <cstring>

#define EMAX 400050
#define VMAX 100005

using namespace std;

const int INF = 0xfffffff;

int head[VMAX],dis[VMAX],cur[VMAX],gap[VMAX],pre[VMAX];
int EN;
struct edge
{
    int from,to;
    int weight;
    int next;
}e[EMAX];

void insert(int u,int v,int w) 
{
    e[EN].from = u;
    e[EN].to = v;
    e[EN].weight = w;
    e[EN].next = head[u];    
    head[u] = EN++;
    e[EN].from = v;
    e[EN].weight = 0;
    e[EN].to = u;
    e[EN].next = head[v];    
    head[v] = EN++;
}

int que[VMAX];

void BFS(int des)
{
    memset(dis, -1, sizeof(dis));
    memset(gap, 0, sizeof(gap));
    gap[0] = 1;
    int front = 0, rear = 0;
    dis[des] = 0;
    que[rear++] = des;
    int u, v;
    while (front != rear)
    {
        u = que[front++];
        front = front%VMAX;
        for (int i=head[u]; i!=-1; i=e[i].next)
        {
            v = e[i].to;
            if (e[i].weight != 0 || dis[v] != -1)
                continue;
            que[rear++] = v;
            rear = rear % VMAX;
            ++gap[dis[v] = dis[u] + 1];
        }
    }
}

int stack[VMAX];
//isap模板
int isap(int src, int des, int n)//源点、汇点、图中点的总数      
{
    int res = 0;
    BFS(des);
    int top = 0;
    memcpy(cur, head, sizeof(head));
    int u = src, i;
    while (dis[src] < n)
    {
        if (u == des)
        {
            int temp = INF, inser = n;
            for (i=0; i!=top; ++i)
                if (temp > e[stack[i]].weight)
                {
                    temp = e[stack[i]].weight;
                    inser = i;
                }
            for (i=0; i!=top; ++i)
            {
                e[stack[i]].weight -= temp;
                e[stack[i]^1].weight += temp;
            }
            res += temp;
            top = inser;
            u = e[stack[top]].from;
        }

        if (u != des && gap[dis[u] -1] == 0)
            break;
        for (i = cur[u]; i != -1; i = e[i].next)
            if (e[i].weight != 0 && dis[u] == dis[e[i].to] + 1)
                break;

        if (i != -1)
        {
            cur[u] = i;
            stack[top++] = i;
            u = e[i].to;
        }
        else
        {
            int min = n;
            for (i = head[u]; i != -1; i = e[i].next)
            {
                if (e[i].weight == 0)
                    continue;
                if (min > dis[e[i].to])
                {
                    min = dis[e[i].to];
                    cur[u] = i;
                }
            }
            --gap[dis[u]];
            ++gap[dis[u] = min + 1];
            if (u != src)
                u = e[stack[--top]].from;
        }
    }
    return res;
}

int main(void)
{
    int t,n,m,x,y,c;
    cin >> t;
    while (t--)
    {
        int west,east,minx=100005,maxx=-100005;
        cin >> n >> m;
        for(int i=1; i<=n; i++)
        {
            cin >> x >> y;
            if (x > maxx)
            {
                east = i;
                maxx = x;
            }
            if (x < minx)
            {
                west = i;
                minx = x;
            }
        }
        memset(head,-1,sizeof(head));
        EN = 0;
        for(int i=1; i<=m; i++)
        {
            cin >> x >> y >> c;
            insert(x,y,c);
            insert(y,x,c);
        }
        cout << isap(west,east,n) << endl;
    }
    return 0;
}

 

posted @ 2014-03-20 23:46  辛力啤  阅读(216)  评论(0编辑  收藏  举报