hdu 3572 Task Schedule ISAP 网络流 构图

在此 dinic 也过时了 

从Lost那里抄过来的模板 复杂度是O(M*(N^2));

而dinic的复杂度也是O(M*(N^2)); 

理论复杂度虽然一样, 但实际却差很多, 这归根于Gap优化, 即相邻顶点标号差严格等于1, 若存在某个顶点标号的顶点数为0,

则说明不存在增广路; 

#include <iostream>
using namespace std;

const int MAXN=1010;
const int MAXM=500010;
typedef  struct {int v,next,val;} edge;

edge e[MAXM];
int p[MAXN],eid, ans;
int n,m;
int h[MAXN];
int gap[MAXN];
int source,sink;

inline void insert(int from,int to,int val)
{
    e[eid].v=to;
    e[eid].val=val;
    e[eid].next=p[from];
    p[from]=eid++;
 
    e[eid].v=from;
    e[eid].val=0;
    e[eid].next=p[to];
    p[to]=eid++;
}

void init()
{
    scanf("%d %d", &n, &m);
    int i, P, S, E, j;
    memset(p, -1, sizeof(p));
    ans = eid = 0;
    for (i = 1; i <= n; ++i)
    {
        scanf("%d %d %d", &P, &S, &E);
        ans += P;
        insert(0, i, P);
        for (j = S; j <= E; ++j)
        {
            insert(i, n+j, 1);
        }
    }
    for (i = 1; i <= 500; ++i)
    {
        insert(i+n, n+500+1, m);
    }
}

inline int dfs(int pos,int cost, int cnt)
{
    if (pos==sink)
    {
        return cost;
    }
 
    int j,minh=cnt-1,lv=cost,d;
 
    for (j=p[pos];j!=-1;j=e[j].next)
    {
        int v=e[j].v,val=e[j].val;
        if(val>0)
        {
            if (h[v]+1==h[pos])
            {    
                if (lv<e[j].val) d=lv;
                else d=e[j].val;
 
                d=dfs(v,d,cnt);
                e[j].val-=d;
                e[j^1].val+=d;
                lv-=d;
                if (h[source]>=cnt) return cost-lv;                
                if (lv==0) break;
            }
 
            if (h[v]<minh)    minh=h[v];
        }
    }
 
    if (lv==cost)
    {
        --gap[h[pos]];
        if (gap[h[pos]]==0) h[source]=cnt;
        h[pos]=minh+1;
        ++gap[h[pos]];
    }
 
    return cost-lv;
 
}
 
int sap(int st,int ed, int cnt)
{
    source=st;
    sink=ed;
    int ret=0;
    memset(gap,0,sizeof(gap));
    memset(h,0,sizeof(h));
 
    gap[st]=cnt;
 
    while (h[st]<cnt)
    {
        ret+=dfs(st,INT_MAX, cnt);
    }
 
    return ret;    
}

int main()
{
    int T, cas = 0;
    scanf("%d", &T);
    while (T--)
    {
        init();
        bool flag = false;
        if (ans == sap(0, n+500+1, n+500+2))
        {
            flag = true;
        }
        printf("Case %d: %s\n\n", ++cas, flag ? "Yes" : "No");
    }
    return 0

} 

posted on 2010-08-25 13:37  ZAFU_VA  阅读(571)  评论(0编辑  收藏  举报

导航