Catch the Theves
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 65768/32768 K (Java/Others)Total Submission(s): 1421 Accepted Submission(s): 431
Problem Description
A 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.
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.
Input
The 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).
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).
Output
For each case,print a line with a number indicating the minimium cost to arrest all thieves.
Sample Input
1 3 10 5 5 6 6 20 4 7 9
Sample Output
18HintThe map is like this:
Source
2011 Multi-University Training Contest 4 - Host by SDU
传送门:【HDU】3870 Catch the Theves
题目大意:现在有一群小偷要从最左上角逃到最右下角,小偷很聪明,每到一个分岔口他们可以分成两拨,现在你是警察,你要阻止他们任何一个逃离到最右下角,已知封锁每条道路的费用,问最少需要花费多少可以达到目的?
题目分析:按照体面理解,就是要我们求全局最小割,但是,网络流不超时几乎是不可能的,16万的点,想想也不太现实。。。。
但是图很特殊,是对偶图,那么我们可以构造这样的一副新图:
新建源汇点,然后平面图的每个面当成一个点,相邻两点间建无向边,边权为两点重叠的边的边权。然后源点S向最左面与最下面的点建边,边权为最左面与最下面的路径的花费,同理汇点T与最上面与最右面建边。
易知每一条S--T的路都是一条割,那么S--T的最短路就是需要求的最小割。
代码如下:
传送门:【HDU】3870 Catch the Theves
题目大意:现在有一群小偷要从最左上角逃到最右下角,小偷很聪明,每到一个分岔口他们可以分成两拨,现在你是警察,你要阻止他们任何一个逃离到最右下角,已知封锁每条道路的费用,问最少需要花费多少可以达到目的?
题目分析:按照体面理解,就是要我们求全局最小割,但是,网络流不超时几乎是不可能的,16万的点,想想也不太现实。。。。
但是图很特殊,是对偶图,那么我们可以构造这样的一副新图:
新建源汇点,然后平面图的每个面当成一个点,相邻两点间建无向边,边权为两点重叠的边的边权。然后源点S向最左面与最下面的点建边,边权为最左面与最下面的路径的花费,同理汇点T与最上面与最右面建边。
易知每一条S--T的路都是一条割,那么S--T的最短路就是需要求的最小割。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REPV( i , a , b ) for ( int i = a ; i >= b ; -- i )
#define clear( a , x ) memset ( a , x , sizeof a )
const int MAXN = 170000 ;
const int MAXE = 700000 ;
const int MAXH = 700000 ;
const int INF = 0x3f3f3f3f ;
struct Edge {
int v , c , n ;
Edge ( int var = 0 , int cost = 0 , int next = 0 ) :
v ( var ) , c ( cost ) , n ( next ) {}
} ;
struct Heap {
int w , idx ;
Heap ( int _w = 0 , int _idx = 0 ) :
w ( _w ) , idx ( _idx ) {}
} ;
struct priority_queue {
Heap heap[MAXH] ;
int top ;
void init () {
top = 1 ;
}
int cmp ( const Heap &a , const Heap &b ) {
return a.w < b.w ;
}
void push ( int w , int idx ) {
heap[top] = Heap ( w , idx ) ;
int o = top ++ ;
while ( o > 1 && cmp ( heap[o] , heap[o >> 1] ) )
swap ( heap[o] , heap[o >> 1] ) , o >>= 1 ;
}
int front () {
return heap[1].idx ;
}
int empty () {
return top == 1 ;
}
void pop () {
heap[1] = heap[-- top] ;
int o = 1 , p = o , l = o << 1 , r = o << 1 | 1 ;
while ( o < top ) {
if ( l < top && cmp ( heap[l] , heap[p] ) )
p = l ;
if ( r < top && cmp ( heap[r] , heap[p] ) )
p = r ;
if ( p == o )
break ;
swap ( heap[o] , heap[p] ) ;
o = p , l = o << 1 , r = o << 1 | 1 ;
}
}
} ;
struct Dij {
priority_queue q ;
Edge edge[MAXE] ;
int adj[MAXN] , cntE ;
int d[MAXN] ;
bool done[MAXN] ;
void init () {
cntE = 0 ;
clear ( adj , -1 ) ;
}
void addedge ( int u , int v , int c ) {
edge[cntE] = Edge ( v , c , adj[u] ) ;
adj[u] = cntE ++ ;
edge[cntE] = Edge ( u , c , adj[v] ) ;
adj[v] = cntE ++ ;
}
void dijkstra ( int s , int t ) {
q.init () ;
clear ( d , INF ) ;
clear ( done , 0 ) ;
d[s] = 0 ;
q.push ( d[s] , s ) ;
while ( !q.empty () ) {
int u = q.front () ;
q.pop () ;
if ( done[u] )
continue ;
done[u] = 1 ;
for ( int i = adj[u] ; ~i ; i = edge[i].n ) {
int v = edge[i].v , c = edge[i].c ;
if ( d[v] > d[u] + c ) {
d[v] = d[u] + c ;
q.push ( d[v] , v ) ;
}
}
}
}
} ;
Dij z ;
void work () {
int n , m ;
int s , t ;
int x ;
z.init () ;
scanf ( "%d" , &n ) ;
m = n - 1 ;
s = m * m ;
t = m * m + 1 ;
REP ( i , n )
REP ( j , n ) {
scanf ( "%d" , &x ) ;
if ( i < m ) {
if ( j == 0 )
z.addedge ( s , i * m + j , x ) ;
else if ( j < m )
z.addedge ( i * m + j - 1 , i * m + j , x ) ;
else if ( j == m )
z.addedge ( i * m + j - 1 , t , x ) ;
}
if ( j < m ) {
if ( i == 0 )
z.addedge ( i * m + j , t , x ) ;
else if ( i < m )
z.addedge ( i * m + j , i * m + j - m , x ) ;
else if ( i == m )
z.addedge ( s , i * m + j - m , x ) ;
}
}
z.dijkstra ( s , t ) ;
printf ( "%d\n" , z.d[t] ) ;
}
int main () {
int T ;
scanf ( "%d" , &T ) ;
while ( T -- )
work () ;
return 0 ;
}