hdu1569 方格取数网络流dinic算法

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<vector>
  6 #include<queue>
  7 using namespace std;
  8 #define inf 0x3f3f3f3f
  9 struct Edge{
 10     int from,to,cap,flow;
 11 };
 12 vector<Edge>edges;
 13 vector<int>G[3005];
 14 int vis[3005],d[3005],cur[3005],map[55][55],s,t;
 15 void addadge(int from,int to,int cap)
 16 {
 17     Edge edge1;
 18     edge1.from=from; edge1.to=to; edge1.cap=cap; edge1.flow=0;
 19     edges.push_back(edge1);
 20     edge1.from=to; edge1.to=from; edge1.cap=0; edge1.flow=0;
 21     edges.push_back(edge1);
 22     int m=edges.size();
 23     G[from].push_back(m-2);
 24     G[to].push_back(m-1);
 25 }
 26 int bfs()
 27 {
 28     memset(vis,0,sizeof(vis));
 29     queue<int>q;
 30     q.push(s); d[s]=0; vis[s]=1;
 31     while (!q.empty())
 32     {
 33         int x=q.front(); q.pop();
 34         for (int i=0;i<G[x].size();i++)
 35         {
 36             Edge& e=edges[G[x][i]];
 37             if (!vis[e.to]&&e.cap>e.flow)
 38             {
 39                 vis[e.to]=1;
 40                 d[e.to]=d[x]+1;
 41                 q.push(e.to);
 42             }
 43         }
 44     }
 45     return vis[t];
 46 }
 47 int dfs(int x,int a)
 48 {
 49     if (x==t||a==0) return a;
 50     int flow=0,f;
 51     for (int& i=cur[x];i<G[x].size();i++)
 52     {
 53         Edge& e=edges[G[x][i]];
 54         if (d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0)
 55         {
 56             e.flow+=f;
 57             edges[G[x][i]^1].flow-=f;
 58             flow+=f; a-=f;
 59             if (a==0) break;
 60         }
 61     }
 62     return flow;
 63 }
 64 int main()
 65 {
 66     int sum,i,j,maxflow,n,m;
 67     while (~scanf("%d%d",&m,&n))
 68     {
 69         sum=0;
 70         for (i=1;i<=m;i++)
 71          for (j=1;j<=n;j++)
 72          {
 73              scanf("%d",&map[i][j]);
 74              sum+=map[i][j];
 75          }
 76         edges.clear();
 77         for (i=0;i<=m*n+1;i++) G[i].clear();
 78         s=0; t=m*n+1;
 79         for (i=1;i<=m;i++)
 80          for (j=1;j<=n;j++)
 81          {
 82              if ((i+j)%2==0)
 83              {
 84                  addadge(s,(i-1)*n+j,map[i][j]);
 85                  if (i>1) addadge((i-1)*n+j,(i-2)*n+j,inf);
 86                  if (i<m) addadge((i-1)*n+j,i*n+j,inf);
 87                  if (j>1) addadge((i-1)*n+j,(i-1)*n+j-1,inf);
 88                  if (j<n) addadge((i-1)*n+j,(i-1)*n+j+1,inf);
 89              }
 90              else addadge((i-1)*n+j,t,map[i][j]);
 91          }
 92         maxflow=0;
 93         while (bfs())
 94         {
 95             memset(cur,0,sizeof(cur));
 96             maxflow+=dfs(s,inf);
 97         }
 98         printf("%d\n",sum-maxflow);
 99     }
100 }

http://acm.hdu.edu.cn/showproblem.php?pid=1569

1、最大点权独立集 = sum - 最小点权覆盖集。
2、最小点权覆盖集 = 最小割 = 最大流

posted on 2014-08-15 01:03  xiao_xin  阅读(149)  评论(0编辑  收藏  举报

导航