网络流(三)----最大流SAP算法

以  HDU 3572  Task Schedule 为例的模板

Code:

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <cctype>

#include <cmath>

#include <algorithm>

#include <vector>

#include <queue>

#include <stack>

#include <map>



using namespace std;



const int inf = 0x3f;

const int INF = 0x3f3f3f3f;

const int maxn = 40002;



struct Node

{

    int to, flow, next;

}edge[maxn * 8];



int n, m;

int S, T;

int tot;



int q[maxn];

int dis[maxn], pre[maxn], rec[maxn], head[maxn];

int gap[maxn], cur[maxn];



inline void Add_edge(int a, int b, int c)

{

    edge[tot].to = b; edge[tot].flow = c; edge[tot].next = head[a];

    head[a] = tot++;

    edge[tot].to = a; edge[tot].flow = 0; edge[tot].next = head[b];

    head[b] = tot++;

}



void Init()

{

    tot = 0; 

    memset(head, -1, sizeof(head));

}



void BFS()

{

    int i; 

    int h = 0, t = 0;

    for(i = 0; i <= T; i++) dis[i] = INF;

    q[h] = T;

    dis[T] = 0;

    while(h <= t)

    {

        int u = q[h++];

        gap[dis[u]]++;

        for(i = head[u]; i != -1; i = edge[i].next)

        {

            int v = edge[i].to;

            if(dis[v] == INF && edge[i^1].flow)

            {

                dis[v] = dis[u] + 1;

                q[++t] = v;

            }

        }

    }

}



int SAP()

{

    int i;

    int u = pre[S] = S, Maxflow = 0, flow = INF;



    for(i = 0; i <= T; i++)//这里 T 为最大顶点编号

    {

        gap[i] = 0;

        cur[i] = head[i];

    }

    BFS();

    while(dis[S] <= T)

    {

        if(u == T)

        {

            Maxflow += flow;

            for(; u != S; u = pre[u])

            {

                edge[rec[u]].flow -= flow;

                edge[rec[u]^1].flow += flow;

            }

            flow = INF;

        }



        for(i = cur[u]; i != -1; i = edge[i].next)

        {

            int v = edge[i].to;

            if(edge[i].flow && dis[u] == dis[v] + 1)

            {

                flow = min(flow, edge[i].flow);

                pre[v] = u;

                rec[v] = i;

                cur[u] = i;//当前弧优化

                u = v;

                break;

            }

        }

        if(i == -1)

        {

            int mindis = T + 1;//T是顶点数

            if((--gap[dis[u]]) == 0) break;//间隙优化

            for(i = cur[u] = head[u]; i != -1; i = edge[i].next)

            {

                if(edge[i].flow && mindis > dis[edge[i].to])

                {

                    mindis = dis[edge[i].to];

                }

            }

            gap[dis[u] = mindis+1]++;

            u = pre[u];

        }

    }

    return Maxflow;

}

int main()

{

    int ncase,n,m;

    scanf("%d",&ncase);

    for(int kase = 1;kase <= ncase;kase++){

        Init();

        scanf("%d%d",&n,&m);

        S = 0,T = 1001;

        int sum = 0;

        for(int i = 1;i <= n;i++){

            int start,process,end;

            scanf("%d%d%d",&process,&start,&end);

            sum += process;

            Add_edge(S,i,process);

            for(int j = start;j <= end;j++)

                Add_edge(i,500+j,1);

        }

        for(int i = 501;i <= 1000;i++)

            Add_edge(i,T,m);

        bool flag = true;

        int tmp = SAP();

        //printf("tmp = %d\n",tmp);

        if(tmp != sum)  flag = false;

        printf("Case %d: ",kase);

        if(flag)    printf("Yes\n\n");

        else        printf("No\n\n");

    }

    return 0;

}

  

你可能感兴趣的:(SAP)