zoukankan      html  css  js  c++  java
  • 网络流(最大流) 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 }
    尽最大的努力,做最好的自己!
  • 相关阅读:
    vim介绍 & vim颜色显示和移动光标& vim一般模式下移动光标 & vim一般模式下复制、剪切和粘贴
    lvm 详解 磁盘故障小案例
    磁盘格式化、磁盘挂载、手动增加swap空间
    df du 磁盘分区
    su sudo 限制root远程登录
    usermod 用户密码管理 mkpasswd
    顺序查找,二分法查找,插值查找算法实现及分析
    完全二叉树的构建及三种遍历
    Mybatis由于类型转换出现的问题
    delimiter解释
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5224864.html
Copyright © 2011-2022 走看看