标签:网络流
#include <cstdio> #include <iostream> #include <cstring> #include <queue> using namespace std; #define INF 0x3fffffff int v[4][2] = {{1,0},{0,1},{-1,0},{0,-1}}; int ma[500][500]; int a[500][500]; int flow[505][505]; int p[500]; int n; int maxflow(int s,int t){ queue<int> q; memset(flow,0,sizeof(flow)); int f = 0; int d[500]; while(1){ memset(d,0,sizeof(d)); d[s] = INF; q.push(s); while(!q.empty()){ int u = q.front(); q.pop(); for(int v = 0; v <= n*n+1; v++){ if(!d[v] && ma[u][v] > flow[u][v]){ p[v] = u; q.push(v); d[v] = min(d[u],ma[u][v] - flow[u][v]); } } } if(d[t] == 0) break; for(int u = t; u != s; u = p[u]){ flow[p[u]][u] += d[t]; flow[u][p[u]] -= d[t]; } f += d[t]; } return f; } int main(){ while(cin >> n){ int sum = 0; memset(ma,0,sizeof(ma)); for(int i = 1;i <= n;i++){ for(int j = 1;j <= n;j++){ cin >> a[i][j]; sum += a[i][j]; } } for(int i = 1;i <= n;i++){ for(int j = 1;j <= n;j++){ if((i+j)%2 == 0){ ma[0][(i-1)*n+j] = a[i][j]; } else{ ma[(i-1)*n+j][n*n+1] = a[i][j]; } } } for(int i = 1;i <= n;i++){ for(int j = 1;j <= n;j++){ for(int k = 0;k < 4;k++){ int x = i + v[k][0]; int y = j + v[k][1]; if(x>0 && x <= n && y > 0 && y<=n && (i+j)%2 == 0){ ma[(i-1)*n + j] [(x-1)*n + y] = INF; } } } } cout <<sum - maxflow(0,n*n+1)<< endl; } return 0; } 定理: 最小割=最大流=最小点权覆盖集=sum - 最大独立点集
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:网络流
原文地址:http://blog.csdn.net/qq_24667639/article/details/46925233