zoukankan      html  css  js  c++  java
  • HDU 3046 Pleasant sheep and big big wolf

    题意:给出一个N*M的矩阵,0表示空地,1表示有一只羊,2表示有一只狼,你可以再图上方格的边缘添加单位长度为1的栅栏使得任意的动物都不能通过。问最少添加多少个单位长度为1的栅栏使得狼抓不到羊。

    是我想的太多了,可能是因为我想少去建条边。其实这里件图建的还是很暴力的。对所有相邻的格子,都建一条cap=1的边,另外,所有有羊的格子,从源点S到羊所在的格子建一条cap=inf的边,对所有有狼的格子,都从有狼的格子到汇点T建一条cap=1的边。求出的最小割容量就是答案。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #define INF 1<<30
     6 #define maxn 41000
     7 #define maxm 400000
     8 using namespace std;
     9 
    10 int v[maxm],next[maxm],w[maxm];
    11 int first[maxn],d[maxn],work[maxn],q[maxn];
    12 int n,m,maxflow,mincost,bg_cnt,e_cnt,t_cnt;
    13 int e,S,T;
    14 
    15 void init(){
    16     e = 0;
    17     memset(first,-1,sizeof(first));
    18 }
    19 
    20 void add_edge(int a,int b,int c){
    21     //printf("add:%d to %d,cap = %d
    ",a,b,c);
    22     v[e] = b;next[e] = first[a];w[e] = c;first[a] = e++;
    23     v[e] = a;next[e] = first[b];w[e] = 0;first[b] = e++;
    24 }
    25 
    26 int bfs(){
    27     int rear = 0;
    28     memset(d,-1,sizeof(d));
    29     d[S] = 0;q[rear++] = S;
    30     for(int i = 0;i < rear;i++){
    31         for(int j = first[q[i]];j != -1;j = next[j])
    32             if(w[j] && d[v[j]] == -1){
    33                 d[v[j]] = d[q[i]] + 1;
    34                 q[rear++] = v[j];
    35                 if(v[j] == T)   return 1;
    36             }
    37     }
    38     return 0;
    39 }
    40 
    41 int dfs(int cur,int a){
    42     if(cur == T)    return a;
    43     for(int &i = work[cur];i != -1;i = next[i]){
    44         if(w[i] && d[v[i]] == d[cur] + 1)
    45             if(int t = dfs(v[i],min(a,w[i]))){
    46                 w[i] -= t;w[i^1] += t;
    47                 return t;
    48             }
    49     }
    50     return 0;
    51 }
    52 
    53 int dinic(){
    54     int ans = 0;
    55     while(bfs()){
    56         memcpy(work,first,sizeof(first));
    57         while(int t = dfs(S,INF))   ans += t;
    58     }
    59     return ans;
    60 }
    61 
    62 int main()
    63 {
    64     int n,m,kase = 0;
    65     while(scanf("%d%d",&n,&m) == 2){
    66         S = 0,T = n*m+1;
    67         init();
    68         for(int i = 1;i <= n;i++){
    69             for(int j = 1;j <= m;j++){
    70                 int pos = (i-1)*m+j;
    71                 if(i > 1)   add_edge(pos,pos-m,1);
    72                 if(i < n)   add_edge(pos,pos+m,1);
    73                 if(j > 1)   add_edge(pos,pos-1,1);
    74                 if(j < m)   add_edge(pos,pos+1,1);
    75                 int tmp;
    76                 scanf("%d",&tmp);
    77                 if(tmp == 1)    add_edge(S,pos,INF);
    78                 if(tmp == 2)    add_edge(pos,T,INF);
    79             }
    80         }
    81         int ans = dinic();
    82         printf("Case %d:
    %d
    ",++kase,ans);
    83     }
    84     return 0;
    85 }
    View Code
  • 相关阅读:
    Excel多工作表快速汇总,简单才是硬道理
    Excel中的条件汇总函数,看过这些你就懂
    SUMPRODUCT函数详解
    关于iOS中的文本操作-管理text fields 和 text views
    ios开发之多线程资源争夺
    关于ios中的文本操作-简介
    ios开发小技巧之提示音播放与震动
    ios开发小技巧之摇一摇截屏
    ios开发之网络数据的下载与上传
    ios开发之网络访问的数据类型
  • 原文地址:https://www.cnblogs.com/zhexipinnong/p/3394291.html
Copyright © 2011-2022 走看看