2 10 3 5 10 3 10 3 3 2 5 3 6 7 10 5 1 2 3 4 5 2 3 4 5 6 3 4 5 6 7 4 5 6 7 8 5 6 7 8 9
28 46 80
和HPU3376一模一样, 但是数据比较弱,果断水了。
具体的解析请看这里 :HPU3376
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define INF 0x3f3f3f3f #define maxn 800000 + 1000 #define maxm 4000000 + 1000 using namespace std; int n; int outset; int inset; struct node { int u, v, cap, flow, cost, next; }; node edge[maxm]; int head[maxn], cnt; int per[maxn]; int dist[maxn], vis[maxn]; int map[660][660]; void init(){ cnt = 0; memset(head, -1, sizeof(head)); } void add(int u, int v, int w, int c){ node E1 = {u, v, w, 0, c, head[u]}; edge[cnt] = E1; head[u] = cnt++; node E2 = {v, u, 0, 0, -c, head[v]}; edge[cnt] = E2; head[v] = cnt++; } int change(int x, int y){ return (x - 1) * n + y; } void getmap(){ int t = n * n; outset = 0; inset = n * n * 2 + 1; for(int i = 1; i <= n; ++i){ for(int j = 1; j <= n; ++j){ scanf("%d", &map[i][j]); if(i == 1 && j == 1 || i == n && j == n) add(change(i, j), change(i, j) + t, 2, map[i][j]); else add(change(i, j), change(i, j) + t, 1, map[i][j]); if(i + 1 <= n) add(change(i, j) + t, change(i + 1, j), 1, 0); if(j + 1 <= n) add(change(i, j) + t, change(i, j + 1), 1, 0); } } add(outset, 1, 2, 0); add(change(n, n) + t, inset, 2, 0); } bool SPFA(int st, int ed){ queue<int>q; for(int i = 0; i <= inset; ++i){ dist[i] = -INF; vis[i] = 0; per[i] = -1; } dist[st] = 0; vis[st] = 1; q.push(st); while(!q.empty()){ int u = q.front(); q.pop(); vis[u] = 0; for(int i = head[u]; i != -1; i = edge[i].next){ node E = edge[i]; if(dist[E.v] < dist[u] + E.cost && E.cap > E.flow){ dist[E.v] = dist[u] + E.cost; per[E.v] = i; if(!vis[E.v]){ vis[E.v] = 1; q.push(E.v); } } } } return per[ed] != -1; } void MCMF(int st, int ed, int &cost, int &flow){ flow = 0; cost = 0; while(SPFA(st, ed)){ int mins = INF; for(int i = per[ed]; i != -1; i = per[edge[i ^ 1].v]){ mins = min(mins, edge[i].cap - edge[i].flow); } for(int i = per[ed]; i != -1; i = per[edge[i ^ 1].v]){ edge[i].flow += mins; edge[i ^ 1].flow -= mins; cost += edge[i].cost * mins; } flow += mins; } } int main (){ while(scanf("%d", &n) != EOF){ init(); getmap(); int cost, flow; MCMF(outset, inset, cost, flow); cost = cost - map[1][1] - map[n][n]; printf("%d\n", cost); } return 0; }