hdu2732 拆点最大流/dinic

看题意看了半天你敢信===

L代表几只蜥蜴的初始位置,一次可以跳到距离<=d的柱子上(曼哈顿距离),柱子最多被跳过次数一定,问最多跳走多少蜥蜴

看懂题意就比较简单的拆点建图了,细节要注意

建边:

  起点到有高度柱子连边,1

  柱子向拆点柱子连边,x

  拆点柱子向可跳跃柱子连边,inf

  拆点柱子如果可以跳到终点向终点连边,inf

输出要注意==

  1 #pragma comment(linker,"/STACK:16777216")
  2 #include<stdio.h>
  3 #include<string.h>
  4 #include<queue>
  5 #include<vector>
  6 #include<algorithm>
  7 #define maxn 100005
  8 #define maxm 200005
  9 #define inf 0x3f3f3f3f
 10 using namespace std;
 11 struct Edge{
 12   int from,to,cap,flow;
 13 };
 14 struct dinic{
 15   int s,t,n;
 16   vector<Edge>edges;
 17   vector<int>G[maxn];
 18   bool vis[maxn];
 19   int cur[maxn],d[maxn];
 20   void init(int _s,int _t,int _n){
 21     s=_s; t=_t; n=_n;
 22     edges.clear();
 23     for (int i=0;i<=_n;i++) G[i].clear();
 24   }
 25   void add(int from,int to,int cap){
 26     Edge e;
 27     e.from=from; e.to=to; e.cap=cap; e.flow=0;
 28     edges.push_back(e);
 29     e.from=to; e.to=from; e.cap=0; e.flow=0;
 30     edges.push_back(e);
 31     int m=edges.size();
 32     G[from].push_back(m-2); G[to].push_back(m-1);
 33   }
 34   bool bfs(){
 35     memset(vis,0,sizeof(vis));
 36     queue<int>q;
 37     q.push(s); d[s]=0; vis[s]=1;
 38     while (!q.empty()){
 39       int x=q.front(); q.pop();
 40       for (int i=0;i<G[x].size();i++){
 41         Edge& e=edges[G[x][i]];
 42         if (!vis[e.to]&&e.cap>e.flow){
 43           vis[e.to]=1;
 44           d[e.to]=d[x]+1;
 45           q.push(e.to);
 46         }
 47       }
 48     }
 49     return vis[t];
 50   }
 51   int dfs(int x,int a){
 52     if (x==t||a==0) return a;
 53     int flow=0,f;
 54     for (int& i=cur[x];i<G[x].size();i++){
 55       Edge& e=edges[G[x][i]];
 56       if (d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){
 57         e.flow+=f;
 58         edges[G[x][i]^1].flow-=f;
 59         flow+=f;
 60         a-=f;
 61         if (a==0) break;
 62       }
 63     }
 64     return flow;
 65   }
 66   int maxflow(){
 67     int flow=0;
 68     while (bfs()){
 69       memset(cur,0,sizeof(cur));
 70       flow+=dfs(s,inf);
 71     }
 72     return flow;
 73   }
 74 }g;
 75 char mp1[25][25],mp2[25][25];
 76 int main()
 77 {
 78   int T,t,n,m,d,ans,i,j,x,y;
 79   scanf("%d",&T);
 80   for (t=1;t<=T;t++){
 81     scanf("%d%d",&n,&d);
 82     for (i=1;i<=n;i++) scanf("%s",mp1[i]);
 83     for (i=1;i<=n;i++) scanf("%s",mp2[i]);
 84     m=strlen(mp1[1]);
 85     ans=0;
 86     g.init(0,2*n*m+1,2*n*m+2);
 87     for (i=1;i<=n;i++)
 88       for (j=0;j<m;j++)
 89         if (mp2[i][j]=='L'){
 90           ans++;
 91           g.add(0,(i-1)*m+j+1,1);
 92         }
 93     for (i=1;i<=n;i++)
 94       for (j=0;j<m;j++)
 95         if (mp1[i][j]!='0'){
 96           g.add((i-1)*m+j+1,(i-1)*m+j+1+n*m,mp1[i][j]-'0');
 97           for (x=1;x<=n;x++)
 98             for (y=0;y<m;y++)
 99             if (mp1[x][y]!='0'&&abs(i-x)+abs(j-y)<=d&&(i!=x||j!=y))
100                 g.add((i-1)*m+j+1+n*m,(x-1)*m+y+1,inf);
101           if (i<=d||j+1<=d||i+d>n||j+d>=m)
102             g.add((i-1)*m+j+1+n*m,2*n*m+1,inf);
103         }
104     ans=ans-g.maxflow();
105     printf("Case #%d: ",t);
106     if (ans==0) printf("no lizard was");
107     else if (ans==1) printf("1 lizard was");
108     else printf("%d lizards were",ans);
109     printf(" left behind.\n");
110   }
111   return 0;
112 }
View Code

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2732

posted on 2015-04-26 01:10  xiao_xin  阅读(84)  评论(0编辑  收藏  举报

导航