BZOJ 1066 [SCOI2007]蜥蜴

PS:变量名引起的血案。。

代名词:dinic,建图,简单网络流,点的流量限制。

step1:当点有容量时把点一分为二,cap为点的容量

step2:加入源点 汇点

step3:每个点 家一个点 我们可以这样加,mp[i][j]=++cnt;cnt++;

     最后一个cnt++ 的cnt是加入的点

step4:源点到每一个石头add(s,y,1);

         每个石头到一个汇点add(y`,t,inf);

       然后我们还要判断该石头能否到外面。

PS:建图小心变量。

  1 #include <stdio.h>
  2 #include <algorithm>
  3 #include <string.h>
  4 #include <iostream>
  5 #include <string>
  6 #include <queue>
  7 #include <string.h>
  8 #include <cmath>
  9 
 10 using namespace std;
 11 
 12 #define N 200240
 13 #define inf 0x3f3f3f
 14 
 15 struct edge
 16 {
 17   int next,v,c;
 18 }e[N<<1];
 19 
 20 int tot,head[N],d[N];
 21 int q[N<<2];
 22 
 23 int min(int a,int b)
 24 {
 25    return a<b?a:b;
 26 }
 27 
 28 void add(int u,int v,int c)
 29 {
 30  e[tot].v=v;e[tot].c=c;
 31  e[tot].next=head[u];head[u]=tot++;
 32 
 33  e[tot].v=u;e[tot].c=0;
 34  e[tot].next=head[v];head[v]=tot++;
 35 }
 36 
 37 int  bfs(int s,int t)
 38 {
 39    memset(d,-1,sizeof(d));
 40    int f=0,r=0;
 41    q[r++]=s;
 42    d[s]=0;
 43 
 44    while (f<r)
 45    {
 46          int u=q[f++];
 47          if (u==t) return 1;
 48          for (int i=head[u];i!=-1;i=e[i].next)
 49          {
 50            int v=e[i].v;
 51            if (d[v]==-1&&e[i].c>0)
 52            {
 53              d[v]=d[u]+1;
 54              q[r++]=v;
 55            }
 56          }
 57    }
 58    return 0;
 59 }
 60 
 61 int dfs(int s,int t,int b)
 62 {
 63   int r=0;
 64   if (s==t) return b;
 65   for (int i=head[s];i!=-1&&r<b;i=e[i].next)
 66   {
 67      int v=e[i].v;
 68      if (e[i].c>0&&d[v]==d[s]+1)
 69      {
 70        int x=min(e[i].c,b-r);
 71        x=dfs(v,t,x);
 72        r+=x;
 73        e[i].c-=x;
 74        e[i^1].c+=x;
 75     }
 76   }
 77   if (!r) d[s]-=2;
 78   return r;
 79 }
 80 
 81 int dinic(int s,int t)
 82 {
 83   int ans=0,tmp;
 84   while (bfs(s,t))
 85   {
 86      while (tmp=dfs(s,t,inf)) ans+=tmp;
 87   }
 88   return ans;
 89 }
 90 void init()
 91 {
 92     tot=0;
 93     memset(head,-1,sizeof(head));
 94 }
 95 
 96 char s[123][123];
 97 char ss[123][123];
 98 int mp[123][123];
 99 
100 int dis(int x,int y,int xx,int yy)
101 {
102     return (xx-x)*(xx-x)+(yy-y)*(yy-y);
103 }
104 
105 
106 int main()
107 {
108    int r,c,d;
109    int cnt=0;
110 
111    scanf("%d%d%d",&r,&c,&d);
112 
113    for (int i=1;i<=r;i++){
114    scanf("%s",s[i]+1);
115    for (int j=1;j<=c;j++)
116    if (s[i][j]!='0'){
117    mp[i][j]=++cnt;
118    cnt++;
119    }
120    }
121 
122    init();
123 
124    for (int i=1;i<=r;i++)
125    scanf("%s",ss[i]+1);
126 
127    int h=0,t=cnt+1;
128 
129    for (int i=1;i<=r;i++)
130    for (int j=1;j<=c;j++)
131    if (s[i][j]>'0')
132    add(mp[i][j],mp[i][j]+1,s[i][j]-'0');
133 
134    int ans=0;
135    for (int i=1;i<=r;i++)
136    for (int j=1;j<=c;j++){
137    if (ss[i][j]=='L')
138    {
139        ans++;
140        add(0,mp[i][j],1);
141    }
142    if (s[i][j]>'0')  {
143    if (i<=d||(r-i)<d||j<=d||(c-j)<d) add(mp[i][j]+1,t,inf);
144    }
145    }
146 
147    for (int i=1;i<=r;i++)
148    for (int j=1;j<=c;j++)
149    {
150        for (int p=1;p<=r;p++)
151        for (int k=1;k<=c;k++)
152        if (!(i==p&&j==k))
153        {
154            if (s[i][j]>'0'&&s[p][k]>'0'&&dis(i,j,p,k)<=d*d)
155            add(mp[i][j]+1,mp[p][k],inf);
156        }
157    }
158    printf("%d\n",ans-dinic(h,t));
159    return 0;
160 }
View Code

 

posted on 2015-04-15 17:03  forgot93  阅读(72)  评论(0编辑  收藏

导航