beloved_ACM

SB,NB,都是一个B.
posts - 29, comments - 2, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

方格取数

Posted on 2010-10-05 22:35 成幸毅 阅读(440) 评论(0)  编辑 收藏 引用
最大点权独立集的问题。不解释。
#include <iostream>
#include 
<queue>
using namespace std;

const int MAXN = 2000;
const int INF = 0x3fffffff;

int c[MAXN][MAXN];
int d[MAXN];
int num[MAXN];
int pre[MAXN];
int s,t,map[MAXN],mat[MAXN][MAXN],value,map2[MAXN]; 

void ini_d(int s,int t) {
   
   memset(num,
0,sizeof(num));
   
for(int i = 0; i <= t; i++)
      d[i] 
= t + 1;
   queue
<int> Q;
   d[t] 
= 0;
   num[
0= 1;
   Q.push(t);
   
int k;
   
while(!Q.empty()) {
      k 
= Q.front();Q.pop();
      
for(int i = 0; i <= t; i++)  {
         
if(c[i][k] >0 && d[i] > t) {
            d[i] 
= d[k] + 1;
            num[d[i]]
++;
            Q.push(i);
         }

      }

   }

}


int findAlowArc(int i) {
   
   
int j;
   
for(j = 0; j <= t;j++)
      
if(c[i][j] > 0 && d[i] == d[j] + 1return j;
   
return -1;
}


int reLable(int i ) {
   
   
int j;
   
int mm = INF;
   
for(j = 0; j <= t; j++{
      
if(c[i][j] > 0) mm = min(mm,d[j] + 1);
   }

   
return mm == INF?t+1:mm;
}


int maxFlow(int s,int t) {
   
   ini_d(s,t);
   
int flow = 0,i = s,j;
   memset(pre,
-1,sizeof(pre));
   
int delta;
   
   
while(d[s] <= t) {
      
      j 
= findAlowArc(i);
      
if(j >= 0{
         pre[j] 
= i;
         i 
= j;
         
if(i == t) {
            delta 
= INF;
            
for(i = t; i != s; i = pre[i]) delta = min(delta,c[pre[i]][i]);
            
for(i = t; i != s; i = pre[i]) {
               c[pre[i]][i] 
-= delta,c[i][pre[i]] += delta;
            }

            flow 
+= delta;
         }

      }

      
else {
         
         
int x = reLable(i);
         num[x]
++;
         num[d[i]]
--;
         
if(num[d[i]] == 0return flow;
         d[i] 
= x;
         
if(i != s) i = pre[i];     
      }

   }

   
return flow;
}


int m,n;

int main() {
   
   
while(scanf("%d%d",&n,&m) != EOF && n && m) {
      
      memset(c,
0,sizeof(c));
      memset(map,
0,sizeof(map));
      memset(map2,
0,sizeof(map2));
      memset(mat,
0,sizeof(mat));
      s 
= 0;
      
int sum = 0;
      
int tot1 = 0, tot2 = 0;
      
for(int i = 1; i <= n;i++{
         
for(int j = 1; j <= m; j++{
           scanf(
"%d",&value);
           sum 
+= value;
           
if((i + j)%2 == 0{
              map[
++tot1] = value; 
              mat[i][j] 
= tot1;
           }

           
else {
              map2[
++tot2] = value;
              mat[i][j] 
= tot2;
           }

         }
  
      }

      
      
for(int i = 1; i <= n; i++)
         
for(int j = 1; j <= m; j++{
            
if((i+j)%2 == 0{
               
if(i - 1 >= 1)
                  c[mat[i][j]][mat[i
-1][j]+tot1] = INF;
               
if(i + 1 <= n) 
                  c[mat[i][j]][mat[i
+1][j]+tot1] = INF;
               
if(j - 1 >= 1
                  c[mat[i][j]][mat[i][j
-1]+tot1] = INF;
               
if(j + 1 <= m)
                  c[mat[i][j]][mat[i][j
+1]+tot1] = INF;
            }

         }

 
      t 
= tot1 + tot2 + 2;
      
      
for(int i = 1; i <= tot1; i++)
         c[s][i] 
= map[i];
      
for(int i = 1; i <= tot2; i++
         c[i
+tot1][t] = map2[i];
      
      
int ans = maxFlow(s,t);
      
      
      printf(
"%d\n",sum - ans);
      
   }

   
  
// system("pause");
   return 0;
}


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理