hdu1569 方格取数(2) (最大流 E_K)模板 邻接表

方格取数(2)

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2580    Accepted Submission(s): 777


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

 

Input
包括多个测试实例,每个测试实例包括2整数m,n和m*n个非负数(m<=50,n<=50)
 

 

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

 

Sample Input
3 3
75 15 21
75 15 28
34 70 5
Sample Output
188
 
心得:卡了好久就是把 n与m 搞混了 = =!!!
vector邻接表实现 E_K
 
View Code
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<fstream>
  4 #include<cstring>
  5 #include<vector>
  6 #include<queue>
  7 #define INF 2<<27
  8 #define N 2510
  9 
 10 using namespace std;
 11 
 12 struct edge{int v,w;};
 13 vector<edge>e[N];
 14 int aa[55][55],flow[N][N],p[N],a[N];
 15 
 16 void build_map(int n,int m)
 17 {
 18     int i,j,u;
 19     edge t;
 20     for(i=0;i<N;i++) e[i].clear(); //在这忘了初始化
 21     for(i=1;i<=n;i++)
 22     {
 23         for(j=1;j<=m;j++)
 24         {
 25             if((i+j)%2==0)
 26             {
 27                 t.v=(i-1)*m+j;t.w=aa[i][j];
 28                 e[0].push_back(t);
 29             }
 30             else
 31             {
 32                 u=(i-1)*m+j;
 33                 t.v=n*m+1;t.w=aa[i][j];
 34                 e[u].push_back(t);
 35             }
 36         }
 37     }
 38     for(i=1;i<=n;i++)
 39     {
 40         for(j=1;j<=m;j++)
 41         {
 42             if((i+j)%2==0)
 43             {
 44                 u=(i-1)*m+j;
 45                 if(j<m)
 46                 {
 47                     t.v=u+1;t.w=INF;
 48                     e[u].push_back(t);
 49                     t.v=u;t.w=0;
 50                     e[u+1].push_back(t);
 51                 }
 52                 if(j>1)
 53                 {
 54                     t.v=u-1;t.w=INF;
 55                     e[u].push_back(t);
 56                     t.v=u;t.w=0;
 57                     e[u-1].push_back(t);
 58                 }
 59                 if(i>1)
 60                 {
 61                     t.v=u-m;t.w=INF;
 62                     e[u].push_back(t);
 63                     t.v=u;t.w=0;
 64                     e[u-m].push_back(t);
 65                 }
 66                 if(i<n)
 67                 {
 68                     t.v=u+m;t.w=INF;
 69                     e[u].push_back(t);
 70                     t.v=u;t.w=0;
 71                     e[u+m].push_back(t);
 72                 }
 73             }
 74         }
 75     }
 76 }
 77 
 78 int E_K(int s,int t)
 79 {
 80     int u,v,w,f=0;
 81     memset(flow,0,sizeof(flow));
 82     queue<int>Q;
 83     while(true)
 84     {
 85         memset(a,0,sizeof(a));
 86         a[s]=INF;
 87         Q.push(s);
 88         while(!Q.empty())
 89         {
 90             u=Q.front();Q.pop();
 91             vector<edge>::iterator it;
 92             for(it=e[u].begin();it<e[u].end();it++)
 93             {
 94                 v=it->v;w=it->w;
 95                 if(!a[v] && w>flow[u][v])
 96                 {
 97                     a[v]=(a[u]<w-flow[u][v]?a[u]:w-flow[u][v]);
 98                     p[v]=u;
 99                     Q.push(v);
100                 }
101             }
102         }
103         if(a[t]==0) break;
104         f+=a[t];
105         for(u=t;u!=s;u=p[u])
106         {
107             flow[p[u]][u]+=a[t];
108             flow[u][p[u]]-=a[t];
109         }
110     }
111     return f;
112 }
113 
114 int main()
115 {
116     int i,j,n,m,sum;
117 #ifndef ONLINE_JUDGE
118     freopen("in.txt","r",stdin);
119 #endif
120     while(cin>>n>>m)
121     {
122         sum=0;
123         memset(aa,0,sizeof(aa));
124         for(i=1;i<=n;i++)
125         {
126             for(j=1;j<=m;j++)
127             {
128                 scanf("%d",&aa[i][j]);
129                 sum+=aa[i][j];
130             }
131         }
132         build_map(n,m);
133         printf("%d\n",sum-E_K(0,n*m+1));
134     }
135     return 0;
136 }

 

posted @ 2012-07-18 23:35  mtry  阅读(787)  评论(0)    收藏  举报