Kakuro Extension最大流
Posted wuliwuliiii
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kakuro Extension最大流相关的知识,希望对你有一定的参考价值。
这道题真的处理起来好复杂啊,题意就是个简单的方格填数问题,但是每个白点至少放1,那么最后的可能解是怎样的呢?我们是不是要把x轴上的和y轴上的统一起来,然后就是每个点都被对应的x和y匹配起来,那么,之后,用每个点的x向y建立边,跑最大流,每个点的放的值就是反向边的权值了。
#include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #define lowbit(x) ( x&(-x) ) #define pi 3.141592653589793 #define e 2.718281828459045 #define INF 0x3f3f3f3f #define HalF (l + r)>>1 #define lsn rt<<1 #define rsn rt<<1|1 #define Lson lsn, l, mid #define Rson rsn, mid+1, r #define QL Lson, ql, qr #define QR Rson, ql, qr #define myself rt, l, r #define MP(x, y) make_pair(x, y) using namespace std; typedef unsigned long long ull; typedef long long ll; const int maxN = 1e2 + 7, maxE = 1e5 + 7, st = 0; pair<int, int> re_xy[20007]; int N, M, head[20007], cur[20007], cnt, ed, id[maxN][maxN], tot, ou[maxN][maxN]; char mp[maxN][maxN][10]; int down[maxN][maxN], righ[maxN][maxN]; struct Eddge int nex, to, flow; Eddge(int a=-1, int b=0, int c=0):nex(a), to(b), flow(c) edge[maxE]; inline void addEddge(int u, int v, int w) edge[cnt] = Eddge(head[u], v, w); head[u] = cnt++; inline void _add(int u, int v, int w) addEddge(u, v, w); addEddge(v, u, 0); inline void solve(int x, int y) if(mp[x][y][1] == ‘X‘ && mp[x][y][7] == ‘X‘) id[x][y] = -1; return; if(mp[x][y][1] == ‘.‘) return; re_xy[++tot] = MP(x, y); id[x][y] = tot; down[x][y] = righ[x][y] = 0; if(mp[x][y][1] != ‘X‘) for(int i=1; i<=3; i++) down[x][y] = down[x][y] * 10 + mp[x][y][i] - ‘0‘; if(mp[x][y][5] != ‘X‘) for(int i=5; i<=7; i++) righ[x][y] = righ[x][y] * 10 + mp[x][y][i] - ‘0‘; int deep[20007]; queue<int> Q; inline bool bfs() for(int i=0; i<=ed; i++) deep[i] = 0; deep[st] = 1; while(!Q.empty()) Q.pop(); Q.push(st); while(!Q.empty()) int u = Q.front(); Q.pop(); for(int i=head[u], v, f; ~i; i=edge[i].nex) v = edge[i].to; f = edge[i].flow; if(f && !deep[v]) deep[v] = deep[u] + 1; Q.push(v); return deep[ed]; int dfs(int u, int Dist) if(u == ed) return Dist; for(int &i=cur[u], v, f; ~i; i=edge[i].nex) v = edge[i].to; f = edge[i].flow; if(f && deep[v] == deep[u] + 1) int di = dfs(v, min(Dist, f)); if(di) edge[i].flow -= di; edge[i^1].flow += di; return di; return 0; inline int Dinic() int ans = 0, tmp; while(bfs()) for(int i=0; i<=ed; i++) cur[i] = head[i]; while((tmp = dfs(st, INF))) ans += tmp; return ans; inline void init() cnt = tot = 0; memset(head, -1, sizeof(head)); memset(id, 0, sizeof(id)); int main() while(scanf("%d%d", &N, &M) != EOF) init(); for(int i=1; i<=N; i++) for(int j=1; j<=M; j++) scanf("%s", mp[i][j] + 1); solve(i, j); ed = (tot << 1) + 1; for(int i=1, le_id=0, up_id=0; i<=N; i++) for(int j=1; j<=M; j++) if(mp[i][j][1] == ‘.‘) for(int dx = i - 1; dx > 0; dx--) if(id[dx][j]) up_id = dx; down[dx][j]--; break; for(int dy = j - 1; dy > 0; dy--) if(id[i][dy]) le_id = dy; righ[i][dy]--; break; _add(id[i][le_id], id[up_id][j] + tot, 8); for(int i=1; i<=N; i++) for(int j=1; j<=M; j++) if(id[i][j] > 0) if(mp[i][j][1] != ‘X‘) _add(id[i][j] + tot, ed, down[i][j]); if(mp[i][j][5] != ‘X‘) _add(st, id[i][j], righ[i][j]); Dinic(); for(int x = 1; x <= tot; x++) for(int i=head[x], y, f; ~i; i=edge[i].nex) y = edge[i].to; f = edge[i^1].flow; if(y == st) continue; ou[re_xy[x].first][re_xy[y - tot].second] = f; for(int i=1; i<=N; i++) for(int j=1; j<=M; j++) if(mp[i][j][1] != ‘.‘) printf("_"); else printf("%d", ou[i][j] + 1); printf("%c", j == M ? ‘\n‘ : ‘ ‘); return 0; /* 3 3 XXXXXXX 009/XXX XXXXXXX XXX/009 ....... XXXXXXX XXXXXXX XXXXXXX XXXXXXX */
以上是关于Kakuro Extension最大流的主要内容,如果未能解决你的问题,请参考以下文章