hdu 3657(最大点权独立集)
2013-05-07 17:16
323 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3657
思路我就不详细讲了,这位大牛讲的很清楚:http://blog.csdn.net/cold__v__moon/article/details/7924269
View Code
思路我就不详细讲了,这位大牛讲的很清楚:http://blog.csdn.net/cold__v__moon/article/details/7924269
View Code
#include<iostream> #include<cstdio> #include<cstring> #define MAXN 55 #define MAXM 55*55 #define inf 1<<30 using namespace std; struct Edge{ int v,cap,next; }edge[MAXM*11]; int map[MAXN][MAXN]; int head[MAXM]; int pre[MAXM]; int cur[MAXM]; int level[MAXM]; int gap[MAXM]; int vs,vt,NV,n,m,k,NE; bool mark[MAXN][MAXN]; int dir[4][2]={{-1,0},{1,0},{0,1},{0,-1}}; void Insert(int u,int v,int cap,int cc=0){ edge[NE].cap=cap;edge[NE].v=v; edge[NE].next=head[u];head[u]=NE++; edge[NE].cap=cc;edge[NE].v=u; edge[NE].next=head[v];head[v]=NE++; } //参数,源点,汇点 int SAP(int vs,int vt){ memset(level,0,sizeof(level)); memset(pre,-1,sizeof(pre)); memset(gap,0,sizeof(gap)); //cur[i]保存的是当前弧 for(int i=0;i<=NV;i++)cur[i]=head[i]; int u=pre[vs]=vs;//源点的pre还是其本身 int maxflow=0,aug=-1; gap[0]=NV; while(level[vs]<NV){ loop : for(int &i=cur[u];i!=-1;i=edge[i].next){ int v=edge[i].v;//v是u的后继 //寻找可行弧 if(edge[i].cap&&level[u]==level[v]+1){ //aug表示增广路的可改进量 aug==-1?(aug=edge[i].cap):(aug=min(aug,edge[i].cap)); pre[v]=u; u=v; //如果找到一条增广路 if(v==vt){ maxflow+=aug;//更新最大流; //路径回溯更新残留网络 for(u=pre[v];v!=vs;v=u,u=pre[u]){ //前向弧容量减少,反向弧容量增加 edge[cur[u]].cap-=aug; edge[cur[u]^1].cap+=aug; } aug=-1; } goto loop; } } int minlevel=NV; //寻找与当前点相连接的点中最小的距离标号(重标号) for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(edge[i].cap&&minlevel>level[v]){ cur[u]=i;//保存弧 minlevel=level[v]; } } if((--gap[level[u]])==0)break;//更新gap数组后如果出现断层,则直接退出。 level[u]=minlevel+1;//重标号 gap[level[u]]++;//距离标号为level[u]的点的个数+1; u=pre[u];//转当前点的前驱节点继续寻找可行弧 } return maxflow; } int main(){ int u,v,sum; while(~scanf("%d%d%d",&n,&m,&k)){ vs=0,vt=n*m+1,NV=vt+1,sum=0,NE=0; memset(mark,false,sizeof(mark)); memset(head,-1,sizeof(head)); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%d",&map[i][j]); sum+=map[i][j]; } } for(int i=1;i<=k;i++){ scanf("%d%d",&u,&v); mark[u][v]=true; } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if((i+j)%2==1){ mark[i][j]?Insert(vs,(i-1)*m+j,inf):Insert(vs,(i-1)*m+j,map[i][j]); for(int l=0;l<4;l++){ int xx=i+dir[l][0],yy=j+dir[l][1]; if(xx>=1&&xx<=n&&yy>=1&&yy<=m){ Insert((i-1)*m+j,(xx-1)*m+yy,(map[i][j]&map[xx][yy])*2); } } }else{ mark[i][j]?Insert((i-1)*m+j,vt,inf):Insert((i-1)*m+j,vt,map[i][j]); } } } printf("%d\n",sum-SAP(vs,vt)); } return 0; }
相关文章推荐
- HDU 3657 Game 网络流--最大独立集
- hdu 3657(最大点权独立集)
- HDU 3657 Game 最大点独立集(最小割)
- hdu 3657(最小割求解最大点权独立集)
- hdu 3657 Game(最小割,最大点权独立集)
- hdu 1068(最大独立集)
- hdu 1565 方格取数(1) 最大点权独立集 网络流
- 方格取数(2) HDU - 1569(二分图最大点权独立集)
- 【HDU】2768 Cat vs. Dog 最大独立集
- HDU 3829 二分最大独立集
- hdu1068-Girls and Boys(最大独立集,匹配问题)
- hdu 1068 Girls and Boys (最大独立集)
- hdu 1068 Girls and Boys(匈牙利算法求最大独立集)
- hdu 1068 Girls and Boys(最大独立集·maxmatch匈牙利)
- (step6.3.2)hdu 1068(Girls and Boys——二分图的最大独立集)
- hdu 3829 Cat VS Dog 二分图匹配 最大点独立集
- hdu 1565 方格取数(1) 最大点权独立集 网络流
- hdu 1569 方格取数(2)--最大点权独立集-->最大流
- HDU 3829 Cat VS Dog(二分图最大独立集)
- hdu 1068 Girls and Boys(最大独立集)