您的位置:首页 > 其它

hdu 1569 最大点权独立集

2013-05-04 10:58 169 查看
和hdu1565很像,但此题必须用邻接表存~

用判断奇偶进行建立二分图

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define inf 99999999
using namespace std;
struct node
{
int u,v,f;
};
node e[60000];
int map[55][55],first[2505],cc;
int next[60000],p[2505];
int a[2505];
inline void add_edge(int u,int v,int f)
{
e[cc].u=u;
e[cc].v=v;
e[cc].f=f;
next[cc]=first[u];
first[u]=cc;
cc++;

e[cc].v=u;
e[cc].u=v;
e[cc].f=0;
next[cc]=first[v];
first[v]=cc;
cc++;
}
int EK(int s,int t)
{
queue<int> q;
int f=0;
while(1)
{
memset(a,0,sizeof(a));
memset(p,-1,sizeof(p));
q.push(s);
a[s]=inf;
while(!q.empty())
{
int u=q.front();
q.pop();
int i;
for(i=first[u];i!=-1;i=next[i])
{
if(!a[e[i].v]&&e[i].f)
{
p[e[i].v]=i;
a[e[i].v]=min(a[u],e[i].f);
q.push(e[i].v);
}
}
}
if(a[t]==0)
break;
int u;
for(u=t;u!=s;u=e[p[u]].u)
{
e[p[u]].f-=a[t];
e[p[u]^1].f+=a[t];
}
f+=a[t];
}
return f;
}
int main()
{
int m,n;
while(scanf("%d%d",&m,&n)!=EOF)
{
int i,j,sum=0;
cc=0;
memset(first,-1,sizeof(first));
memset(next,-1,sizeof(next));
for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
scanf("%d",&map[i][j]),sum+=map[i][j];
int s=0,t=n*m+1;
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)
{
int tmp=(i-1)*n+j;
if((i+j)%2==0)
{
add_edge(s,tmp,map[i][j]);
if(i>1)
add_edge(tmp,(i-2)*n+j,inf);
if(i<m)
add_edge(tmp,i*n+j,inf);
if(j>1)
add_edge(tmp,(i-1)*n+j-1,inf);
if(j<n)
add_edge(tmp,(i-1)*n+j+1,inf);
}
else
add_edge(tmp,t,map[i][j]);
}

}
int ans=EK(s,t);
printf("%d\n",sum-ans);

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: