#include<stdio.h>
#include<string.h>
const int MAXN= 610;
const __int64 maxint = 1000000000000000ll;
struct edge
{
int x,ne;
__int64 cost;
} e[8*MAXN*MAXN];
int st, ed, te, top, hd[4*MAXN*MAXN],rr[4*MAXN*MAXN];
__int64 heap[4*MAXN*MAXN],d[4*MAXN*MAXN],r[4*MAXN*MAXN],tmp;
void link(int x,int y,__int64 cost)
{
te++;
e[te].x=y;
e[te].ne=0;
e[te].cost=cost;
if (hd[x])
{
e[rr[x]].ne=te;
rr[x]=te;
}
else rr[x]=hd[x]=te;
}
__int64 pop()
{
__int64 t=heap[1];
int i=1,flag=1;
r[1]=r[heap[top]];
heap[1]=heap[top--]; //trail[pt++]=t;
while (flag)
{
flag=0;
if (top>=i*2+1 && d[heap[i]]>d[heap[i*2+1]] && d[heap[i*2]]>d[heap[i*2+1]])
{
flag=1;
tmp=r[heap[i]];
r[heap[i]]=r[heap[i*2+1]];
r[heap[i*2+1]]=tmp;
tmp=heap[i];
heap[i]=heap[i*2+1];
heap[i*2+1]=tmp;
i=i*2+1;
}
else if (top>=i*2 && d[heap[i]]>d[heap[i*2]])
{
flag=1;
tmp=r[heap[i]];
r[heap[i]]=r[heap[i*2]];
r[heap[i*2]]=tmp;
tmp=heap[i];
heap[i]=heap[i*2];
heap[i*2]=tmp;
i=i*2;
}
}
return t;
}
void dij()
{
int i,j;
__int64 ii, k;
top=ed+1;
for(i=0; i<=top; i++)
{
heap[i+1]=i;
d[i]=maxint;
r[i]=i+1;
}
d[0]=0;
j=hd[k=st];
while (j)
{
if (d[e[j].x]>d[k]+e[j].cost)
{
d[e[j].x]=d[k]+e[j].cost;
ii=r[e[j].x];
while (ii!=1 && d[heap[ii]]<d[heap[ii/2]])
{
tmp=r[heap[ii]];
r[heap[ii]]=r[heap[ii/2]];
r[heap[ii/2]]=tmp;
tmp=heap[ii];
heap[ii]=heap[ii/2];
heap[ii/2]=tmp;
ii/=2;
}
}
j=e[j].ne;
}
for (i=st; i<=ed; i++)
{
k=pop();
j=hd[k];
while (j)
{
if (d[e[j].x]>d[k]+e[j].cost)
{
d[e[j].x]=d[k]+e[j].cost;
ii=r[e[j].x];
while (ii!=1 && d[heap[ii]]<d[heap[ii/2]])
{
tmp=r[heap[ii]];
r[heap[ii]]=r[heap[ii/2]];
r[heap[ii/2]]=tmp;
tmp=heap[ii];
heap[ii]=heap[ii/2];
heap[ii/2]=tmp;
ii/=2;
}
}
j=e[j].ne;
}
}
printf("%I64d\n",d[ed]);
}
int main()
{
int n;
scanf("%d", &n);
te = 0;
memset(hd, 0, sizeof(hd));
st = 0;
ed = n * n + 1;
int x;
for(int i = 0; i <= n; i++)
for(int j = 0; j < n; j++)
{
scanf("%d", &x);
int p = i * n + j + 1;
int q = p - n;
if(i == 0) link(st, p, x);
else if(i == n) link(q, ed, x);
else link(q, p, x);
}
for(int i = 0; i < n; i++)
for(int j = 0; j <= n; j++)
{
scanf("%d", &x);
int p = i * n + j + 1;
int q = p - 1;
if(j == 0) link(p, ed, x);
else if(j == n) link(st, q, x);
else link(p, q, x);
}
for(int i = 0; i <= n; i++)
for(int j = 0; j < n; j++)
{
scanf("%d", &x);
int p = i * n + j + 1;
int q = p - n;
if(i == 0) link(p, st, x);
else if(i == n) link(ed, q, x);
else link(p, q, x);
}
for(int i = 0; i < n; i++)
for(int j = 0; j <= n; j++)
{
scanf("%d", &x);
int p = i * n + j + 1;
int q = p - 1;
if(j == 0) link(ed, p, x);
else if(j == n) link(q, st, x);
else link(q, p, x);
}
dij();
return 0;
}
NOI 2010 海拔 //有向边的平面图最小割
最新推荐文章于 2021-08-28 10:19:03 发布