您的位置:首页 > 其它

[BZOJ1001]Beijing2006 狼抓兔子|平面图转对偶图

2015-04-17 09:06 246 查看
最小割非常裸。。但是数据范围很大,跑最大流肯定要T掉。。所以要平面图转对偶图跑最短路。。具体看这里:浅析最大最小定理在信息学竞赛中的应用

#include<iostream>
#include<stdio.h>
#include<malloc.h>
#include<memory.h>
using namespace std;
struct point{
int e,q;
point *next;
};
point *a[2000010],*p;
int i,j,n,m,q,t,s,que[2000010],f[2000010],u[2000010],sw=10000000,ne=10000000;
void addedge(int s,int e,int q)
{p=(point*)malloc(sizeof(point));
p->e=e;
p->q=q;
p->next=a[s];
a[s]=p;
}
void init()
{//part1---------------------------------
for (i=1;i<=m-1;i++)
{scanf("%d",&q);
addedge(i,t,q);
addedge(t,i,q);
if (i==m-1) ne=min(ne,q);
}
for (i=2;i<=n-1;i++)
for (j=1;j<=m-1;j++)
{scanf("%d",&q);
addedge((2*i-3)*(m-1)+j,(2*i-2)*(m-1)+j,q);
addedge((2*i-2)*(m-1)+j,(2*i-3)*(m-1)+j,q);
}
for (i=1;i<=m-1;i++)
{scanf("%d",&q);
if (i==1) sw=min(sw,q);
addedge((2*n-3)*(m-1)+i,s,q);
addedge(s,(2*n-3)*(m-1)+i,q);
}
//part2----------------------------------
for (i=1;i<=n-1;i++)
for (j=1;j<=m;j++)
{scanf("%d",&q);
if (i==n-1&&j==1)
{sw=min(sw,q);
if (q>=sw) continue;
p=(point*)malloc(sizeof(point));
p=a[s];
while (p->e!=(2*n-3)*(m-1)+1)
p=p->next;
p->q=sw;
continue;
}
if (i==1&&j==m)
{ne=min(ne,q);
if (q>=ne) continue;
p=(point*)malloc(sizeof(point));
p=a[t];
while (p->e!=m-1)
p=p->next;
p->q=ne;
continue;
}
if (j==1)
{addedge((2*i-1)*(m-1)+1,s,q);
addedge(s,(2*i-1)*(m-1)+1,q);
continue;
}
if (j==m)
{addedge((2*i-1)*(m-1),t,q);
addedge(t,(2*i-1)*(m-1),q);
continue;
}
addedge((2*i-1)*(m-1)+j,(2*i-2)*(m-1)+j-1,q);
addedge((2*i-2)*(m-1)+j-1,(2*i-1)*(m-1)+j,q);
}
//part3----------------------------------
for (i=1;i<=n-1;i++)
for (j=1;j<=m-1;j++)
{scanf("%d",&q);
addedge((2*i-2)*(m-1)+j,(2*i-1)*(m-1)+j,q);
addedge((2*i-1)*(m-1)+j,(2*i-2)*(m-1)+j,q);
}
}
void spfa(int s)
{int head=1,tail=1,get,hh=1,tt=1;
memset(que,0,sizeof(que));
que[1]=s;
p=(point*)malloc(sizeof(point));
memset(f,1,sizeof(f));
memset(u,0,sizeof(u));
u[s]=1;
f[s]=0;
while (hh<=tt)
{get=que[head];
p=a[get];
while (p!=0)
{if (f[get]+p->q<f[p->e])
{f[p->e]=p->q+f[get];
if (u[p->e]==0)
{tail++;tt++;
if (tail>2000000) tail=1;
que[tail]=p->e;
u[p->e]=1;
}
}
p=p->next;
}
u[get]=0;
head++;hh++;
if (head>2000000) head=1;
}
}
int main()
{freopen("rabbit.in","r",stdin);
scanf("%d%d",&n,&m);
if (n==1||m==1)
{int ans=999999999;
for (i=1;i<=n+m-2;i++)
{scanf("%d",&q);
ans=min(ans,q);
}
printf("%d",ans);
return 0;
}
s=(n-1)*(m-1)*2+1;
t=s+1;
init();
spfa(s);
printf("%d",f[t]);
fclose(stdin);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: