zoukankan      html  css  js  c++  java
  • HDU1569+最大点权集

      1 /*
      2 最大点权独立集=总权值-最小点权覆盖集
      3 最大点权独立集=最大流
      4 最小点权覆盖集=最小割
      5 
      6 题意:
      7 给你一个m*n的格子的棋盘,每个格子里面有一个非负数。
      8 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大。
      9 根据奇偶建立二分图,
     10 if(i+j)%2==0 源点和该点连接,权值为该点的点权,
     11 if(i+j)%2==1 该点和汇点连接,权值为该点的点权,
     12 之后若i+j为偶数的点和i+j为奇数的点之间相邻,那么就连一条从为偶数的点到为奇数的点的边,权值为无穷大
     13 */
     14 #include<stdio.h>
     15 #include<string.h>
     16 #include<stdlib.h>
     17 #include<algorithm>
     18 #include<iostream>
     19 #include<math.h>
     20 using namespace std;
     21 const int inf = 0x3f3f3f3f;
     22 const int maxn = 2605;
     23 const int maxm = 30005;
     24 const int dx[]={1,-1,0,0};
     25 const int dy[]={0,0,1,-1};
     26 struct Node{
     27     int u,v,next,val;
     28 }edge[ maxm ];
     29 int head[ maxn ],cnt;
     30 void init(){
     31     cnt = 0;
     32     memset( head,-1,sizeof( head ) );
     33 }
     34 void addedge( int a,int b,int c ){
     35     edge[ cnt ].u = a;
     36     edge[ cnt ].v = b;
     37     edge[ cnt ].val = c;
     38     edge[ cnt ].next = head[ a ];
     39     head[ a ] = cnt++;
     40     
     41     edge[ cnt ].u = b;
     42     edge[ cnt ].v = a;
     43     edge[ cnt ].val = 0;
     44     edge[ cnt ].next = head[ b ];
     45     head[ b ] = cnt++;
     46 }
     47 
     48 int queue[ maxn ];
     49 int lev[ maxn ];
     50 int Dinic( int start,int end ){
     51     int max_flow = 0;
     52     while( true ){
     53         int Head,Tail,id;
     54         Head = Tail = 0;
     55         queue[ Tail++ ] = start;
     56         memset( lev,-1,sizeof( lev ) );
     57         lev[ start ] = 0;
     58         while( Head<Tail ){
     59             id = head[ queue[ Head++ ] ];
     60             while( id!=-1 ){
     61                 if( edge[ id ].val>0&&lev[edge[id].v]==-1 ){
     62                     lev[edge[id].v] = lev[edge[id].u]+1;
     63                     queue[Tail++] = edge[id].v;
     64                     if( edge[id].v==end ){
     65                         Head = Tail;
     66                         break;//分层完成
     67                     }
     68                 }
     69                 id = edge[id].next;
     70             }
     71         }//bfs构造层次网络
     72         
     73         if( lev[end]==-1 ) break;
     74         
     75         id = start;
     76         Tail = 0;
     77         //这里queue被当作stack来用
     78         while( true ){//层次网络中进行dfs
     79             if( id==end ){//dfs找到汇点
     80                 int flow = inf;
     81                 int flag = -1;
     82                 for( int i=0;i<Tail;i++ ){
     83                     if( edge[queue[i]].val<flow ){
     84                         flow = edge[queue[i]].val;
     85                         flag = i;
     86                     }
     87                 }//寻找最小的边
     88                 for( int i=0;i<Tail;i++ ){
     89                     edge[ queue[i] ].val -= flow;
     90                     edge[ queue[i]^1 ].val += flow;
     91                 }
     92                 if( flag!=-1 )
     93                 {
     94                     max_flow += flow;
     95                     Tail = flag;
     96                     id = edge[ queue[flag] ].u;
     97                 }
     98                 else
     99                     return inf;
    100             }
    101             id = head[ id ];
    102             while( id!=-1 ){
    103                 if( edge[id].val>0&&(lev[edge[id].u]+1==lev[edge[id].v]) ){
    104                     break;
    105                 }
    106                 id = edge[id].next;
    107             }
    108             if( id!=-1 ){
    109                 queue[Tail++] = id;
    110                 id = edge[id].v;
    111             }
    112             else{
    113                 if( Tail==0 ) break;
    114                 lev[ edge[queue[Tail-1]].v ] = -1;
    115                 id = edge[queue[--Tail]].u;
    116             }
    117         }
    118     }
    119     return max_flow;
    120 }
    121 int main(){
    122     int m,n;
    123     while( scanf("%d%d",&n,&m)!=EOF ){
    124         init();
    125         int sum = 0;
    126         int temp;
    127         for( int i=1;i<=n;i++ ){
    128             for( int j=1;j<=m;j++ ){
    129                 scanf("%d",&temp);
    130                 if( (i+j)%2==0 ){
    131                     addedge( 0,(i-1)*m+j,temp );
    132                 }
    133                 else{
    134                     addedge( (i-1)*m+j,n*m+1,temp );
    135                 }
    136                 sum += temp;
    137             }
    138         }
    139         for( int i=1;i<=n;i++ ){
    140             for( int j=1;j<=m;j++ ){
    141                 if( (i+j)%2==0 ){
    142                     for( int k=0;k<4;k++ ){
    143                         int tx = i+dx[k];
    144                         int ty = j+dy[k];
    145                         if( tx>=1&&tx<=n&&ty>=1&&ty<=m ){
    146                             addedge( (i-1)*m+j,(tx-1)*m+ty,inf );
    147                         }
    148                     }
    149                 }
    150             }
    151         }
    152         int start = 0;
    153         int end = n*m+1;
    154         int ans = Dinic( start,end );
    155         //printf("sum = %d,ans = %d
    ",sum,ans);
    156         printf("%d
    ",sum-ans);
    157     }
    158     return 0;
    159 }
    View Code
    keep moving...
  • 相关阅读:
    SQL Server 创建用户自定义数据类型
    用输入法敲打键盘时字体之间的间隔突然变大了,是怎么回事?
    SQL Server 增加自增ID列
    Python安装cv2模块不成功
    Python错误20009:pymssql._pymssql.OperationalError) (20009, b'DB-Lib error message 20009, severity 9: Unable to connect: Adaptive Server is unavailable or does not exist ')
    Python 获取父级目录
    谷歌上网助手Ghelper
    Python连接MySQL数据库
    Python用pandas获取Excel数据
    Python连接MySQL数据库获取数据绘制柱状图
  • 原文地址:https://www.cnblogs.com/xxx0624/p/3236427.html
Copyright © 2011-2022 走看看