网络流(最大流) HDU 1565 方格取数(1) HDU 1569 方格取数(2)

 
HDU 1565 方格取数(1)
给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。

Input

包括多个测试实例,每个测试实例包括一个整数n 和n*n个非负数(n<=20)

Output

对于每个测试实例,输出可能取得的最大的和

Sample Input

3
75 15 21 
75 15 28 
34 70 5 

Sample Output

188
直接用这个程序拿双倍经验吧~
  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <queue>
  5 
  6 using namespace std;
  7 const int INF=2147483647;
  8 const int maxn=10010,maxm=1000010;
  9 int cnt,fir[maxn],nxt[maxm],cap[maxm],to[maxm],dis[maxn],gap[maxn],path[maxn];
 10 int map[53][53];
 11 void addedge(int a,int b,int c)
 12 {
 13     nxt[++cnt]=fir[a];
 14     to[cnt]=b;
 15     cap[cnt]=c;
 16     fir[a]=cnt;
 17 }
 18 
 19 bool BFS(int S,int T)
 20 {
 21     memset(dis,0,sizeof(dis));
 22     dis[T]=1;
 23     queue<int>q;q.push(T);
 24     while(!q.empty())
 25     {
 26         int node=q.front();q.pop();
 27         for(int i=fir[node];i;i=nxt[i])
 28         {
 29             if(dis[to[i]])continue;
 30             dis[to[i]]=dis[node]+1;
 31             q.push(to[i]);
 32         }
 33     }
 34     return dis[S];
 35 }
 36 int fron[maxn];
 37 int ISAP(int S,int T)
 38 {
 39     if(!BFS(S,T))
 40         return 0;
 41     for(int i=1;i<=T;i++)++gap[dis[i]];
 42     int p=S,ret=0;
 43     memcpy(fron,fir,sizeof(fir));
 44     while(dis[S]<=T)
 45     {
 46         if(p==T){
 47             int f=INF;
 48             while(p!=S){
 49                 f=min(f,cap[path[p]]);
 50                 p=to[path[p]^1];
 51             }
 52             p=T;ret+=f;
 53             while(p!=S){
 54                 cap[path[p]]-=f;
 55                 cap[path[p]^1]+=f;
 56                 p=to[path[p]^1];
 57             }
 58         }
 59         int &ii=fron[p];
 60         for(;ii;ii=nxt[ii]){
 61             if(!cap[ii]||dis[to[ii]]+1!=dis[p])
 62                 continue;
 63             else 
 64                 break;
 65         }
 66         if(ii){
 67             p=to[ii];
 68             path[p]=ii;
 69         }
 70         else{
 71             if(--gap[dis[p]]==0)break;
 72             int minn=T+1;
 73             for(int i=fir[p];i;i=nxt[i])
 74                 if(cap[i])
 75                     minn=min(minn,dis[to[i]]);
 76             gap[dis[p]=minn+1]++;
 77             fron[p]=fir[p];
 78             if(p!=S)
 79                 p=to[path[p]^1];        
 80         }
 81     }
 82     return ret;
 83 }
 84 
 85 void Init()
 86 {
 87     memset(fir,0,sizeof(fir));
 88     memset(gap,0,sizeof(gap)); 
 89     cnt=1;
 90 }
 91 
 92 int n,m;
 93 
 94 int dot(int x,int y){
 95     return (x-1)*m+y;
 96 }
 97 
 98 int main()
 99 {
100     int sum;
101     while(~scanf("%d%d",&n,&m))
102     {
103         Init();sum=0;
104         for(int i=1;i<=n;i++)
105             for(int j=1;j<=m;j++){
106             scanf("%d",&map[i][j]);
107             sum+=map[i][j]; 
108         } 
109         
110         for(int i=1;i<=n;i++)
111             for(int j=1;j<=m;j++)
112                 if((i+j)%2==1){
113                     addedge(0,(i-1)*m+j,map[i][j]);
114                     addedge((i-1)*m+j,0,0);
115                 }     
116             
117         for(int i=1;i<=n;i++)
118             for(int j=1;j<=m;j++)
119                 if((i+j)%2==0){
120                     addedge((i-1)*m+j,n*m+1,map[i][j]);
121                     addedge(n*m+1,(i-1)*m+j,0);
122                 } 
123         
124         for(int i=1;i<=n;i++)
125             for(int j=1;j<=m;j++)
126                 if((i+j)%2==1){
127                     if(i+1<=n){
128                         addedge(dot(i,j),dot(i+1,j),INF);
129                         addedge(dot(i+1,j),dot(i,j),0);
130                     }
131                     if(i-1>=1){
132                         addedge(dot(i,j),dot(i-1,j),INF);
133                         addedge(dot(i-1,j),dot(i,j),0);
134                     }if(j-1>=1){
135                         addedge(dot(i,j),dot(i,j-1),INF);
136                         addedge(dot(i,j-1),dot(i,j),0);
137                     }
138                     if(j+1<=m){
139                         addedge(dot(i,j),dot(i,j+1),INF);
140                         addedge(dot(i,j+1),dot(i,j),0);
141                     }
142                     
143                 }
144         printf("%d
",sum-ISAP(0,n*m+1));
145     }
146     return 0;
147 }
尽最大的努力,做最好的自己!
原文地址:https://www.cnblogs.com/TenderRun/p/5224864.html