Kaka's Matrix Travels(최대 요금 흐름)

Kaka's Matrix Travels
Time Limit:1000MS  Memory Limit:65536KTotal Submit:6 Accepted:3
Description
On an N × N chessboard with a non-negative number in each grid, Kaka starts his matrix travels with SUM = 0. For each travel, Kaka moves one rook from the left-upper grid to the right-bottom one, taking care that the rook moves only to the right or down. Kaka adds the number to SUM in each grid the rook visited, and replaces it with zero. It is not difficult to know the maximum SUM Kaka can obtain for his first travel. Now Kaka is wondering what is the maximum SUM he can obtain after his Kth travel. Note the SUM is accumulative during the K travels.
Input
The first line contains two integers N and K (1 ≤ N ≤ 50, 0 ≤ K ≤ 10) described above. The following N lines represents the matrix. You can assume the numbers in the matrix are no more than 1000.
Output
The maximum SUM Kaka can obtain after his Kth travel.
Sample Input
3 2
1 2 3
0 2 1
1 4 2

 
Sample Output
15

 
Source
POJ Monthly--2007.10.06, Huang, Jinsong
 
 
#include #include #include #include #include using namespace std; #define M 51 const int sz = 75000; const int INF = 200000000; struct Edge { int v,w,capacity; int next; }adj[sz * 8]; int head[sz],pre[sz],dist[sz],road[sz],src,dest,k; bool inq[sz]; void init(const int &n) { src = 0; dest = n; k = 0; fill(head,head+n+1,-1); } void add(const int &v1,const int &v2,const int &w,const int &capacity) { adj[k].v = v2; adj[k].w = w; adj[k].capacity = capacity; adj[k].next = head[v1]; head[v1] = k++; } void addEdge(const int &v1,const int &v2,const int &w,const int &capacity) { add(v1,v2,w,capacity); add(v2,v1,-w,0); } bool SPFA(int n) { fill(dist,dist+n*n*2+1,INF); fill(inq,inq+n*n*2+1,false); inq[src] = true; dist[src] = 0; queue < int > q; q.push(src); while(!q.empty()) { int t = q.front(); q.pop(); inq[t] = false; int index = head[t]; while(index != -1) { if(adj[index].capacity > 0 && dist[t] + adj[index].w < dist[adj[index].v]) { dist[adj[index].v] = dist[t] + adj[index].w; pre[adj[index].v] = t; road[adj[index].v] = index; if(!inq[adj[index].v]) { q.push(adj[index].v); inq[adj[index].v] = true; } } index = adj[index].next; } } return (dist[dest] != INF); } int minCostMaxFlow(int n) { int minCost = 0,t,nowCost; while(SPFA(n)) { int flow = INF; for(t = dest ; t != src ; t = pre[t] ) { if(adj[road[t]].capacity < flow) flow = adj[road[t]].capacity; } nowCost=0; for(t = dest ; t != src ; t = pre[t] ) { adj[road[t]].capacity -= flow;//positive edge capacity -= flow adj[road[t]^1].capacity += flow;//nagative edge capacity += flow//cout< 
제목 대의: n*n(1<=n<=50)의 행렬을 드리겠습니다. 칸마다 값array[i][j]가 있습니다.만약 i행 제j열의 좌표가 (i, j)라고 가정하면 점(i, j)은 점(i+1, j)과 점(i, j+1)까지만 갈 수 있다. 즉, 오른쪽과 아래로 갈 수 있다.점(1,1)에서 점(n,n)까지 K번을 가면 얻을 수 있는 최대치를 묻는다. 칸마다 처음 지나갈 때만 총액이 붙는다.
문제 풀이 사고방식: 최대 비용 최대 흐름.각 칸을 하나의 점 A로 보고 이 점 A를 두 개의 점 A와 A로 뜯어라.만약에 점 B가 점 A의 오른쪽이나 아래에 있다면 점 A'는 점 B와 하나의 비용이 0이고 용량은 무한한 가장자리이다.두 개의 점 A와 A에 대해 점 A가 점 A로 연결되는 비용은 점 A라는 칸의 값, 용량이 1인 변과 한 개의 비용은 0이고 용량은 무한한 변이다.소스 S 를 하나 더 만듭니다.S와 점 C(1,1)는 하나의 비용이 0이고 용량은 K의 가장자리이며 송금점은 점 D'(n,n)로 정한다.그리고 점 S에서 점 D'(n, n)까지의 최대 비용 최대 흐름을 구할 수 있습니다.

좋은 웹페이지 즐겨찾기