hdu 1565&&hdu 1569 (最大点权独立集)

题目意思很明确就是选一些没有相连的数字,使和最大,建成二分图后求最大点权独立集,,





 

#include<stdio.h>

#include<string.h>

const int N=2510;

const int inf=0x3fffffff;

int dis[N],gap[N],head[N],num,start,end,ans;

struct edge

{

	int ed,flow,next;

}e[N*6];

void addedge(int x,int y,int w)

{

	e[num].ed=y;e[num].flow=w;e[num].next=head[x];head[x]=num++;

	e[num].ed=x;e[num].flow=0;e[num].next=head[y];head[y]=num++;

}

int dfs(int u,int minflow)

{

	if(u==end)return minflow;

	int i,v,f,min_dis=ans-1,flow=0;

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

	{

		v=e[i].ed;

		if(e[i].flow<=0)continue;

		if(dis[v]+1==dis[u])

		{

			f=dfs(v,e[i].flow>minflow-flow?minflow-flow:e[i].flow);

			e[i].flow-=f;

			e[i^1].flow+=f;

			flow+=f;

			if(flow==minflow)break;

			if(dis[start]>=ans)return flow;

		}

		min_dis=min_dis>dis[v]?dis[v]:min_dis;

	}

	if(flow==0)

	{

		if(--gap[dis[u]]==0)

			dis[start]=ans;

		dis[u]=min_dis+1;

		gap[dis[u]]++;

	}

	return flow;

}

int isap()

{

	int maxflow=0;

	memset(dis,0,sizeof(dis));

	memset(gap,0,sizeof(gap));

	gap[0]=ans;

	while(dis[start]<ans)

		maxflow+=dfs(start,inf);

	return maxflow;

}

int main()

{

	int i,n,w,j,x,sum,m;

	while(scanf("%d%d",&n,&m)!=-1)

	{

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

		num=0;sum=0;start=0;end=n*m+1;ans=end+1;

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

		{

			for(j=1;j<=m;j++)

			{

				x=i*m+j-m;

				scanf("%d",&w);

				sum+=w;

				if((i+j)%2!=0)

					addedge(x,end,w);

				else 

				{

					addedge(start,x,w);

					if(i>1)addedge(x,x-m,inf);

					if(j>1)addedge(x,x-1,inf);

					if(i<n)addedge(x,x+m,inf);

					if(j<m)addedge(x,x+1,inf);

				}

			}

		}

		printf("%d\n",sum-isap());

	}

	return 0;

}


 

 

你可能感兴趣的:(HDU)