hdu 1569 方格取数(2)//最小割

#include<cstdio> #include<cstring> const int MAXN=10010; const int MAXM=100000; const int INF = 0x7fffffff; struct Edge { int st, ed,next,flow; } edge[MAXM]; int head[MAXN],value[MAXN]; int N, M, F, E; int src, dest; int seq[MAXM], sl; int ans = 0; int map[101][101]; void add_edge(int u, int v, int w) { edge[E].flow = w; edge[E].st = u; edge[E].ed = v; edge[E].next = head[u]; head[u] = E++; edge[E].flow = 0; edge[E].st = v; edge[E].ed = u; edge[E].next = head[v]; head[v] = E++; } int d[MAXN]; bool dinic_bfs(void) { int i, j; memset(d, -1, sizeof(d)); int que[MAXN], rear = 1; que[0] = src; d[src] = 0; for(i = 0; i < rear; i++) { for(j = head[que[i]]; j != -1; j = edge[j].next) { if(d[edge[j].ed] == -1 && edge[j].flow > 0) { d[edge[j].ed] = d[que[i]]+1; que[rear++] = edge[j].ed; if(edge[j].ed==dest) return true; } } } return false; } int dinic_dfs(void) { int stk[MAXN], top = 0; int ret = 0, cur, ptr, pre[MAXN], minf, i; bool del[MAXN]; memset(del, false, sizeof(del)); stk[top++] = src; pre[src] = src; cur = src; while(top) { while(cur != dest && top) { for(i = head[cur]; i != -1; i = edge[i].next) { if(d[edge[i].ed] == d[cur]+1 && edge[i].flow > 0 && !del[edge[i].ed]) { stk[top++] = edge[i].ed; cur = edge[i].ed; pre[edge[i].ed] = i; break; } } if(i == -1) { del[cur] = 1; top--; if(top) cur = stk[top-1]; } } if(cur == dest) { minf = INF; while(cur != src) { cur = pre[cur]; if(edge[cur].flow < minf) minf = edge[cur].flow; cur = edge[cur].st; } cur = dest; while(cur != src) { cur = pre[cur]; edge[cur].flow -= minf; edge[cur^1].flow += minf; if(edge[cur].flow == 0) ptr = edge[cur].st; cur = edge[cur].st; } while(top > 0&& stk[top-1] != ptr) top--; if(top) cur = stk[top-1]; ret += minf; } } return ret; } int Dinic() { int ret = 0, t; while(dinic_bfs()) { t = dinic_dfs(); if(t) ret += t; else break; } return ret; } int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { src=0; dest=n*m+1; E=0; memset(head,-1,sizeof(head)); int sum=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%d",&map[i][j]); sum+=map[i][j]; } for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) { int t=(i-1)*m+j; if((i+j)%2==0) { add_edge(0,t,map[i][j]); if(i+1<=n) add_edge(t,t+m,INF); if(j+1<=m) add_edge(t,t+1,INF); } else { add_edge(t,n*m+1,map[i][j]); if(i+1<=n) add_edge(t+m,t,INF); if(j+1<=m) add_edge(t+1,t,INF); } } printf("%d/n",sum-Dinic()); } return 0; }  

你可能感兴趣的:(hdu 1569 方格取数(2)//最小割)