Catch the Theves
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 65768/32768 K (Java/Others)Total Submission(s): 313 Accepted Submission(s): 105
Zjsxzy decided to caught these thieves,and he let the police to do this,the police try to catch them on their way from A to B. Although the thieves might travel this way by more than one group, zjsxzy's excellent police has already gather the statistics that the cost needed on each road to guard it.
Now ,zjsxzy's conutry can be described as a N*N matrix A,Aij indicates the city(i,j) have bidirectionals road to city(i+1,j) and city(i,j+1),gurad anyone of them costs Aij.
Now give you the map,help zjsxzy to calculate the minimium cost.We assume thieves may travel in any way,and we will catch all passing thieves on a road if we guard it.
In each test case,the first line contains a number N(1<N<=400).
The following N lines,each line is N numbers,the jth number of the ith line is Aij.
The city A is always located on (1,1) and the city B is always located on (n,n).
Of course,the city (i,j) at the last row or last line won't have road to (i,j+1) or (i+1,j).
1 3 10 5 5 6 6 20 4 7 9
18HintThe map is like this:![]()
/*
平面图最小割转换为最短路
s-t连边增加一个s平面,除了s-t平面,其它平面有相邻则连边。
*/
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#define N 400*400
using namespace std;
int t,n,a[405][405];
int v,e,low[N],p[N],q[N],adj[N];
bool f[N];
struct Edge
{
int v,w,next;
}edge[4*N];
void insert(int u,int v,int w)
{
edge[e].v=v;edge[e].w=w;
edge[e].next=adj[u];
adj[u]=e++;
}
int spfa(int s)
{
memset(f,0,sizeof(f));
memset(low,0x7f,sizeof(low));
//fill(low,low+n*n+5,999999999);
int i,j,k,x,h=0,t=1;
v=n*n+1;
q[t]=s;
low[s]=0;
while(h!=t)
{
h=(h+1)%(v+1);
x=q[h];
f[x]=0;
for(k=adj[x];k!=-1;k=edge[k].next)
{
i=edge[k].v;
j=edge[k].w;
if(j+low[x]<low[i])
{
low[i]=low[x]+j;
if(!f[i])
{
f[i]=1;
t=(t+1)%(v+1);
q[t]=i;
}
}
}
}
return low[n*n+1];
}
int main()
{
scanf("%d",&t);
while(t--)
{
memset(adj,-1,sizeof(adj));
int i,j;
e=0;
scanf("%d",&n);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&a[i][j]);
n--;
for(i=0;i<n;i++)
{
insert(0,i*n+1,a[i][0]);
insert(0,(n-1)*n+i+1,a[n][i]);//s平面
insert(i+1,n*n+1,a[0][i]);
insert(i*n+n,n*n+1,a[i][n]);//t平面
for(j=0;j<n;j++)
{
if(j+1<n)
{
insert(i*n+j+1,i*n+j+2,a[i][j+1]);
insert(i*n+j+2,i*n+j+1,a[i][j+1]);//相邻平面
}
if(i+1<n)
{
insert(i*n+j+1,(i+1)*n+j+1,a[i+1][j]);
insert((i+1)*n+j+1,i*n+j+1,a[i+1][j]);//相邻平面
}
}
}
printf("%d\n",spfa(0));
}
}
7285



被折叠的 条评论
为什么被折叠?



