方格取数
Time Limit: 1000ms
Memory Limit: 65535KB
This problem will be judged on HRBUST. Original ID: 121464-bit integer IO format: %lld Java class name: Main
设有N*N的方格图(N<=10),我们将其中的某些方格中填入正整数,而其他的方格中则放人数字0。如下图所示(见样例 ,黄色和蓝色分别为两次走的路线,其中绿色的格子为黄色和蓝色共同走过的):
A
|
|||||||
13 | 6 | ||||||
7 | |||||||
14 | |||||||
21 | 4 | ||||||
15 | |||||||
14 | |||||||
B
|
某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角的B 点。在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字0)。此人从A点到B点共走两次,试找出2条这样的路径,使得取得的数之和为最大
。
Input
有多组测试数据,每组格式如下:
第一行为一个整数N(表示N*N的方格图),接下来的每行有三个整数,前两个表示位置,第三个数为该位置上所放的数。一行单独的0表示输入结束。
第一行为一个整数N(表示N*N的方格图),接下来的每行有三个整数,前两个表示位置,第三个数为该位置上所放的数。一行单独的0表示输入结束。
Output
与输入对应,有多组输出,每组只需输出一个整数,表示2条路径上取得的最大的和。
Sample Input
8
2 3 13
2 6 6
3 5 7
4 4 14
5 2 21
5 6 4
6 3 15
7 2 14
0 0 0
2 3 13
2 6 6
3 5 7
4 4 14
5 2 21
5 6 4
6 3 15
7 2 14
0 0 0
Sample Output
67
Source
解题:拆点费用流。见http://www.cnblogs.com/crackpotisback/p/3971435.html
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <climits> 7 #include <vector> 8 #include <queue> 9 #include <cstdlib> 10 #include <string> 11 #include <set> 12 #include <stack> 13 #define LL long long 14 #define pii pair<int,int> 15 #define INF 0x3f3f3f3f 16 using namespace std; 17 const int maxn = 400; 18 struct arc{ 19 int v,w,f,next; 20 arc(int x = 0,int y = 0,int z = 0,int nxt = 0){ 21 v = x; 22 w = y; 23 f = z; 24 next = nxt; 25 } 26 }; 27 arc e[1000]; 28 int head[maxn],d[maxn],p[maxn],S,T,n,mp[15][15],tot; 29 bool in[maxn]; 30 queue<int>q; 31 void add(int u,int v,int w,int f){ 32 e[tot] = arc(v,w,f,head[u]); 33 head[u] = tot++; 34 e[tot] = arc(u,-w,0,head[v]); 35 head[v] = tot++; 36 } 37 bool spfa(){ 38 for(int i = 0; i < maxn; i++){ 39 d[i] = INF; 40 in[i] = false; 41 p[i] = -1; 42 } 43 while(!q.empty()) q.pop(); 44 d[S] = 0; 45 in[S] = true; 46 q.push(S); 47 while(!q.empty()){ 48 int u = q.front(); 49 q.pop(); 50 in[u] = false; 51 for(int i = head[u]; ~i; i = e[i].next){ 52 if(e[i].f > 0 && d[e[i].v] > d[u] + e[i].w){ 53 d[e[i].v] = d[u] + e[i].w; 54 p[e[i].v]= i; 55 if(!in[e[i].v]){ 56 in[e[i].v] = true; 57 q.push(e[i].v); 58 } 59 } 60 } 61 } 62 return p[T] > -1; 63 } 64 int solve(){ 65 int tmp = 0,minV; 66 while(spfa()){ 67 minV = INF; 68 for(int i = p[T]; ~i; i = p[e[i^1].v]) 69 minV = min(minV,e[i].f); 70 for(int i = p[T]; ~i; i = p[e[i^1].v]){ 71 e[i].f -= minV; 72 e[i^1].f += minV; 73 tmp += minV*e[i].w; 74 } 75 } 76 return tmp; 77 } 78 int main() { 79 int x,y,w; 80 while(~scanf("%d",&n)){ 81 memset(mp,0,sizeof(mp)); 82 memset(head,-1,sizeof(head)); 83 S = tot = 0; 84 T = n*n*2+1; 85 while(scanf("%d %d %d",&x,&y,&w),x||y||w) mp[x][y] = w; 86 for(int i = 1; i <= n; i++){ 87 for(int j = 1; j <= n; j++){ 88 add(n*(i-1)+j,n*(i-1)+j+n*n,-mp[i][j],1); 89 add(n*(i-1)+j,n*(i-1)+j+n*n,0,INF); 90 if(i < n) add(n*(i-1)+j+n*n,n*i+j,0,INF); 91 if(j < n) add(n*(i-1)+j+n*n,n*(i-1)+j+1,0,INF); 92 } 93 } 94 add(S,1,0,2); 95 add(n*n*2,T,0,2); 96 printf("%d ",-solve()); 97 } 98 return 0; 99 }