hdu 4859 最大点权独立集的变形(方格取数的变形)
来源:互联网 发布:java 继承 构造函数 编辑:程序博客网 时间:2024/06/05 08:18
/*刚开始不会写,最大点权独立集神马都不知道,在潘神的指导下终于做出来,灰常感谢ps;和方格取数差不多奇偶建图,对于D必割点权为0,对于.必然不割点权为inf。然后和方格取数差不多的建图.--.||E权值为2,,.||E--D权值为0.最大点权独立集=sum-最小点权覆盖。*/#include<stdio.h>#include<string.h>#include<queue>using namespace std;#define inf 0x3fffffff#define ii 50#define N 3000struct node { int u,v,w,next;}bian[N*6];int head[N],yong,s,t,dis[N];void init(){yong=0;memset(head,-1,sizeof(head));memset(dis,-1,sizeof(dis));}void addedge(int u,int v,int w) {bian[yong].u=u;bian[yong].v=v;bian[yong].w=w;bian[yong].next=head[u];head[u]=yong++;}void add(int u,int v,int w) { addedge(u,v,w); addedge(v,u,0);}void bfs() {int u,v,i;queue<int>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 ;}int ISAP() {int sum=0;bfs();int 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];}int k=s;top=0;while(dis[s]<t+1) { if(k==t) { int minn=inf,index; for(i=0;i<top;i++) { int e=stac[i]; if(minn>bian[e].w) { minn=bian[e].w; index=i; } } for(i=0;i<top;i++) { int 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) { int 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) { int 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() { int n,m,i,j,T,id[ii][ii],cnt,sum,f=0; char ss[ii][ii]; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); cnt=1;sum=0; init(); for(i=1;i<=n;i++) { scanf("%s",ss[i]+1); for(j=1;j<=m;j++) { if(ss[i][j]=='.'||ss[i][j]=='E')//记录总数 sum+=4; id[i][j]=cnt++; } } s=0;t=n*m+1; for(i=1;i<=n;i++) for(j=1;j<=m;j++) { if((i+j)&1) {//奇偶建图与源点相连 if(ss[i][j]=='.') add(s,id[i][j],inf);//必然不割 if(ss[i][j]=='D')//必割 add(s,id[i][j],0); if(ss[i][j]=='E')//任意选择 add(s,id[i][j],4); if(i>=2) { if(ss[i][j]=='.'||ss[i][j]=='E') { if(ss[i-1][j]=='.'||ss[i-1][j]=='E')add(id[i][j],id[i-1][j],2);// if(ss[i-1][j]=='D')add(id[i][j],id[i-1][j],0);// } else add(id[i][j],id[i-1][j],0); } if(j>=2) { if(ss[i][j]=='.'||ss[i][j]=='E') { if(ss[i][j-1]=='.'||ss[i][j-1]=='E')add(id[i][j],id[i][j-1],2); if(ss[i][j-1]=='D')add(id[i][j],id[i][j-1],0); } else add(id[i][j],id[i][j-1],0); } if(i<=n-1){ if(ss[i][j]=='.'||ss[i][j]=='E') { if(ss[i+1][j]=='.'||ss[i+1][j]=='E')add(id[i][j],id[i+1][j],2); if(ss[i+1][j]=='D')add(id[i][j],id[i+1][j],0); } else add(id[i][j],id[i+1][j],0); } if(j<=m-1) { if(ss[i][j]=='.'||ss[i][j]=='E') { if(ss[i][j+1]=='.'||ss[i][j+1]=='E')add(id[i][j],id[i][j+1],2); if(ss[i][j+1]=='D')add(id[i][j],id[i][j+1],0); } else add(id[i][j],id[i][j+1],0); } } else {//与汇点相连 if(ss[i][j]=='.') add(id[i][j],t,inf); if(ss[i][j]=='E') add(id[i][j],t,4); if(ss[i][j]=='D') add(id[i][j],t,0); } } printf("Case %d: ",++f); printf("%d\n",sum-ISAP()); }return 0;}
0 0
- hdu 4859 最大点权独立集的变形(方格取数的变形)
- hdu 3657最大点权独立集变形(方格取数变形)
- hdu 3657 最大点权独立集变形(方格取数的变形最小割,对于最小割建图很好的题)
- HDU 1569 方格取数(2) (二分图的最大点权独立集)
- hdu 1569 方格取数 最大点权独立集(hdu 1565)
- hdu 1565 方格取数(1)(最小割,最大点权独立集)
- HDU 1565 1569 方格取数(最大点权独立集)
- hdu 1569 方格取数 点最大独立集
- ★ 方格取数3 二分图的最大点权独立集
- hdu 1569 方格取数(2)--最大点权独立集-->最大流
- HDU 1565 & HDU 1569 方格取数 | 最大点权独立集
- [网络流][最大点权独立集] 方格取数
- hdu1569 方格取数 求最大点权独立集
- 【最大点权独立集】【HDU1565】【方格取数】
- 方格取数(2)(最大点权独立集)
- 【codevs1907】方格取数3 最大点权独立集
- 【BZOJ 1475】方格取数 最大点权独立集
- [hdu1569]方格取数(2) 最大点权独立集
- hdu 1058
- UVa 12657 Boxes in a Line(双向链表的应用)
- MySql创建数据库的语句
- 简单回顾windows下的SVN用法
- 将一个文件夹下的所有文件和文件夹更改用户和用户组
- hdu 4859 最大点权独立集的变形(方格取数的变形)
- SoftReference,对象的强、软、弱和虚引用
- [新手入门][拓扑排序]
- web开发学习--JS初级学习对话框
- WebCollector 2.x 入门教程
- C++学习第2天——函数的申明与调用
- The Perfect Stall
- dom4j组装xml 以及解析xml
- hdu 1087