hdu 1569 最大权独立集

/*最大点权独立集=sum-最小点权覆盖*/
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define inf 0x3fffffff
#define ll __int64
#define N   3000
struct node
{
    ll u,v,w,next;
}bian[N*N*2];
ll  ma[N][N],id[N][N],head[N],yong,s,t,dis[N];;
void addedge(ll u,ll v,ll w)
{
    bian[yong].u=u;
    bian[yong].v=v;
    bian[yong].w=w;
    bian[yong].next=head[u];
    head[u]=yong++;
}
void add(ll u,ll v,ll w)
{
    addedge(u,v,w);
    addedge(v,u,0);
}
void init()
{
    yong=0;
    memset(head,-1,sizeof(head));
    memset(dis,-1,sizeof(dis));
}
void bfs()
{
    ll u,v,i;
    queue<ll>q;
    q.push(t);
    dis[t]=0;
    while(!q.empty())
    {
        u=q.front();
        q.pop();
        for(i=head[u]; i!=-1; i=bian[i].next)
        {
            v=bian[i].v;
            if(dis[v]==-1)
            {
                dis[v]=dis[u]+1;
                q.push(v);
            }
        }
    }
    return ;
}
ll ISAP()
{
    ll sum=0;
    bfs();
    ll  gap[N],cur[N],stac[N],top,i;
    memset(gap,0,sizeof(gap));
    for(i=s; i<=t; i++)
    {
        gap[dis[i]]++;
        cur[i]=head[i];
    }
    ll k=s;
    top=0;
    while(dis[s]<t+1)
    {
        if(k==t)
        {
            ll minn=inf,index;
            for(i=0; i<top; i++)
            {
                ll e=stac[i];
                if(minn>bian[e].w)
                {
                    minn=bian[e].w;
                    index=i;
                }
            }
            for(i=0; i<top; i++)
            {
                ll e=stac[i];
                bian[e].w-=minn;
                bian[e^1].w+=minn;
            }
            sum+=minn;
            top=index;
            k=bian[stac[top]].u;
        }
        for(i=cur[k]; i!=-1; i=bian[i].next)
        {
            ll  v=bian[i].v;
            if(bian[i].w&&dis[k]==dis[v]+1)
            {
                cur[k]=i;
                k=v;
                stac[top++]=i;
                break;
            }
        }
        if(i==-1)
        {
            ll m=t+1;
            for(i=head[k]; i!=-1; i=bian[i].next)
                if(m>dis[bian[i].v]&&bian[i].w)
                {
                    m=dis[bian[i].v];
                    cur[k]=i;
                }
            if(--gap[dis[k]]==0)break;
            gap[dis[k]=m+1]++;
            if(k!=s)
                k=bian[stac[--top]].u;
        }
    }
    return sum;
}
int main()
{
    ll n,m,i,j,cnt;
    ll sum;
    while(scanf("%I64d%I64d",&n,&m)!=EOF)
    {
        init();
        cnt=1;
        sum=0;s=0;t=n*m+1;
        for(i=1; i<=n; i++)
            for(j=1; j<=m; j++)
            {
                scanf("%I64d",&ma[i][j]);
                id[i][j]=cnt++;
                sum+=ma[i][j];
            }
        for(i=1; i<=n; i++)
            for(j=1; j<=m; j++)
            {
                if((i+j)&1)
                {
                    add(s,id[i][j],ma[i][j]);
                    if(i<=n-1)
                        add(id[i][j],id[i+1][j],inf);
                    if(j<=m-1)
                        add(id[i][j],id[i][j+1],inf);
                        if(i>=2)
                            add(id[i][j],id[i-1][j],inf);
                        if(j>=2)
                            add(id[i][j],id[i][j-1],inf);
                    }
                else
                    add(id[i][j],t,ma[i][j]);
            }
        printf("%I64d
",sum-ISAP());
    }
    return 0;
}

原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410660.html