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
Problem DescriptionA group of thieves is approaching a museum in the country of zjsxzy,now they are in city A,and the museum is in city B,where keeps many broken legs of zjsxzy.Luckily,GW learned the conspiracy when he is watching stars and told it to zjsxzy.
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.
InputThe first line is an integer T,followed by T test cases.
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).
OutputFor each case,print a line with a number indicating the minimium cost to arrest all thieves.
Sample Input
1310 5 56 6 204 7 9
Sample Output
18HintThe map is like this:
Source2011 Multi-University Training Contest 4 - Host by SDU 具體見國家集訓隊2008論文周冬《兩極相通——淺析最大—最小定理在資訊學競賽中的應用》將s-t連一條邊,新增一個s面,最外面的為t面,每一個面當做新圖的一個頂點。除了s-t面,相鄰兩個面連一條邊,求s-t的最短路即是原圖的最小割。 code:
/*平面圖最小割轉換為最短路s-t連邊增加一個s平面,除了s-t平面,其它平面有相鄰則連邊。*/#include<cstdio>#include<vector>#include<queue>#include<algorithm>#define N 400*400using 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));}}