1、题意:一个裸的最小割
2、分析:直接转成对偶图最短路就好了,水爆了!(雾)
#include <queue> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; #define M 2000010 #define inf 1014748364 inline int read(){ char ch = getchar(); int x = 0, f = 1; while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while('0' <= ch && ch <= '9'){ x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } namespace dijkstra{ struct Edge{ int u, v, w, next; } G[M]; int head[M], tot; struct Node{ int d, u; inline bool operator < (const Node& rhs) const{ return d > rhs.d; } }; priority_queue<Node> Q; int d[M]; bool done[M]; inline void init(){ memset(head, -1, sizeof(head)); tot = 0; } inline void add(int u, int v, int w){ // printf("%d %d %d\n", u, v, w); G[++ tot] = (Edge){u, v, w, head[u]}; head[u] = tot; } inline int get_dis(int s, int t, int n){ memset(done, 0, sizeof(done)); for(int i = 0; i <= n; i ++) d[i] = inf; d[s] = 0; Q.push((Node){0, s}); while(!Q.empty()){ Node u = Q.top(); Q.pop(); int x = u.u; if(done[x]) continue; done[x] = 1; for(int i = head[x]; i != -1; i = G[i].next){ Edge& e = G[i]; if(d[e.v] > d[x] + e.w){ d[e.v] = d[x] + e.w; Q.push((Node){d[e.v], e.v}); } } } return d[t]; } } using namespace dijkstra; int n; inline int num(int i, int j){ if(j < 1 || i > n) return 0; if(i < 1 || j > n) return n * n + 1; return (i - 1) * n + j; } int main(){ n = read(); init(); for(int i = 0; i <= n; i ++){ for(int j = 1; j <= n; j ++){ int x = read(); add(num(i + 1, j), num(i, j), x); } } for(int i = 1; i <= n; i ++){ for(int j = 0; j <= n; j ++){ int x = read(); add(num(i, j), num(i, j + 1), x); } } for(int i = 0; i <= n; i ++){ for(int j = 1; j <= n; j ++){ int x = read(); add(num(i, j), num(i + 1, j), x); } } for(int i = 1; i <= n; i ++){ for(int j = 0; j <= n; j ++){ int x = read(); add(num(i, j + 1), num(i, j), x); } } printf("%d\n", get_dis(0, n * n + 1, n * n + 1)); return 0; }