zoukankan      html  css  js  c++  java
  • bzoj 1412 [ZJOI2009]狼和羊的故事(最小割)

    【题目链接】

        http://www.lydsy.com/JudgeOnline/problem.php?id=1412

    【题意】

        在一个n*m的格子中,将羊和狼隔开的最小代价。

    【思路】

        最小割。

        由S向狼连边inf,由羊向T连边inf,由狼向空格和羊连边1,由空格向四周连边为1,跑一遍最小割。

    【代码】

      1 #include<cmath>
      2 #include<queue>
      3 #include<vector>
      4 #include<cstdio>
      5 #include<cstring>
      6 #include<iostream>
      7 #include<algorithm>
      8 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
      9 using namespace std;
     10 
     11 const int N = 1e4+10;
     12 const int inf = 1e9;
     13 const int dx[]={0,0,1,-1};
     14 const int dy[]={1,-1,0,0};
     15 
     16 struct Edge{ int u,v,cap,flow;
     17 };
     18 struct Dinic {
     19     int n,m,s,t;
     20     int d[N],cur[N],vis[N];
     21     vector<Edge> es; 
     22     vector<int> g[N];
     23     queue<int> q;
     24     void init(int n) {
     25         this->n=n;
     26         es.clear();
     27         for(int i=0;i<=n;i++) g[i].clear();
     28     }
     29     void AddEdge(int u,int v,int w) {
     30         es.push_back((Edge){u,v,w,0});
     31         es.push_back((Edge){v,u,0,0});
     32         m=es.size();
     33         g[u].push_back(m-2),
     34         g[v].push_back(m-1);
     35     }
     36     bool bfs() {
     37         memset(vis,0,sizeof(vis));
     38         q.push(s); d[s]=0; vis[s]=1;
     39         while(!q.empty()) {
     40             int u=q.front(); q.pop();
     41             for(int i=0;i<g[u].size();i++) {
     42                 Edge& e=es[g[u][i]];
     43                 int v=e.v;
     44                 if(!vis[v] && e.cap>e.flow) {
     45                     d[v]=d[u]+1;
     46                     vis[v]=1;
     47                     q.push(v);
     48                 }
     49             }
     50         }
     51         return vis[t];
     52     }
     53     int dfs(int u,int a) {
     54         if(u==t || a==0) return a;
     55         int flow=0,f;
     56         for(int& i=cur[u];i<g[u].size();i++) {
     57             Edge& e=es[g[u][i]];
     58             int v=e.v;
     59             if(d[v]==d[u]+1 && (f=dfs(v,min(a,e.cap-e.flow)))>0) {
     60                 e.flow+=f;
     61                 es[g[u][i]^1].flow-=f;
     62                 flow+=f; a-=f;
     63                 if(!a) break;
     64             }
     65         }
     66         return flow;
     67     }
     68     int MaxFlow(int s,int t) {
     69         this->s=s,this->t=t;
     70         int flow=0;
     71         while(bfs()) {
     72             memset(cur,0,sizeof(cur));
     73             flow+=dfs(s,inf);
     74         }
     75         return flow;
     76     }
     77 } dc;
     78 
     79 int n,m;
     80 int mp[105][105];
     81 
     82 bool inside(int x,int y) 
     83 {
     84     return x>=1&&x<=n&&y>=1&&y<=m;
     85 }
     86 
     87 int main()
     88 {
     89     scanf("%d%d",&n,&m);
     90     dc.init(n*m+3);
     91     int s=0,t=n*m+1;
     92     FOR(i,1,n) FOR(j,1,m) scanf("%d",&mp[i][j]);
     93     FOR(i,1,n) FOR(j,1,m) {
     94         if(mp[i][j]==1) dc.AddEdge(s,(i-1)*m+j,inf);
     95         else if(mp[i][j]==2) dc.AddEdge((i-1)*m+j,t,inf);
     96         int x=i,y=j;
     97         if(mp[x][y]==2) continue;
     98         FOR(k,0,3) {
     99             int nowx=x+dx[k],nowy=y+dy[k];
    100             if(!inside(nowx,nowy)) continue;
    101             if(mp[x][y]!=1||mp[nowx][nowy]!=1) 
    102                 dc.AddEdge((x-1)*m+y,(nowx-1)*m+nowy,1);
    103         }
    104     }
    105     printf("%d
    ",dc.MaxFlow(s,t));
    106     return 0;
    107 }
  • 相关阅读:
    start tag, end tag issues in IE7, particularly in xslt transformation
    用SandCastle为注释生成chm文档
    Firebug
    架构的重点
    Linux Shell常用技巧(十) 管道组合
    Linux JDK升级
    Linux Shell常用技巧(十二) Shell编程
    Packet Tracer 5.0实验(一) 交换机的基本配置与管理
    Linux Shell常用技巧(六) sort uniq tar split
    Linux Shell常用技巧(二) grep
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5279287.html
Copyright © 2011-2022 走看看