# BZOJ 1066 蜥蜴 最大流

https://www.lydsy.com/JudgeOnline/problem.php?id=1066

  1 #include<bits/stdc++.h>
2 #define IOS ios::sync_with_stdio(false);//不可再使用scanf printf
3 #define Max(a, b) ((a) > (b) ? (a) : (b))//禁用于函数，会超时
4 #define Min(a, b) ((a) < (b) ? (a) : (b))
5 #define Mem(a) memset(a, 0, sizeof(a))
6 #define Dis(x, y, x1, y1) ((x - x1) * (x - x1) + (y - y1) * (y - y1))
7 #define MID(l, r) ((l) + ((r) - (l)) / 2)
8 #define lson ((o)<<1)
9 #define rson ((o)<<1|1)
10 #define Accepted 0
12 using namespace std;
14 {
15     int x=0,f=1;char ch=getchar();
16     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
17     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 typedef long long ll;
21 const int maxn = 1000 + 10;
22 const int MOD = 1000000007;//const引用更快，宏定义也更快
23 const int INF = 1e9 + 7;
24 const double eps = 1e-6;
25 struct edge
26 {
27     int u, v, c, f;
28     edge(int u, int v, int c, int f):u(u), v(v), c(c), f(f){}
29 };
30 vector<edge>e;
31 vector<int>G[maxn];
32 int level[maxn];//BFS分层，表示每个点的层数
33 int iter[maxn];//当前弧优化
34 int m;
35 void init(int n)
36 {
37     for(int i = 0; i <= n; i++)G[i].clear();
38     e.clear();
39 }
40 void addedge(int u, int v, int c)
41 {
42     //cout<<u<<" "<<v<<" "<<c<<endl;
43     e.push_back(edge(u, v, c, 0));
44     e.push_back(edge(v, u, 0, 0));
45     m = e.size();
46     G[u].push_back(m - 2);
47     G[v].push_back(m - 1);
48 }
49 void BFS(int s)//预处理出level数组
50 //直接BFS到每个点
51 {
52     memset(level, -1, sizeof(level));
53     queue<int>q;
54     level[s] = 0;
55     q.push(s);
56     while(!q.empty())
57     {
58         int u = q.front();
59         q.pop();
60         for(int v = 0; v < G[u].size(); v++)
61         {
62             edge& now = e[G[u][v]];
63             if(now.c > now.f && level[now.v] < 0)
64             {
65                 level[now.v] = level[u] + 1;
66                 q.push(now.v);
67             }
68         }
69     }
70 }
71 int dfs(int u, int t, int f)//DFS寻找增广路
72 {
73     if(u == t)return f;//已经到达源点，返回流量f
74     for(int &v = iter[u]; v < G[u].size(); v++)
75         //这里用iter数组表示每个点目前的弧，这是为了防止在一次寻找增广路的时候，对一些边多次遍历
76         //在每次找增广路的时候，数组要清空
77     {
78         edge &now = e[G[u][v]];
79         if(now.c - now.f > 0 && level[u] < level[now.v])
80             //now.c - now.f > 0表示这条路还未满
81             //level[u] < level[now.v]表示这条路是最短路，一定到达下一层，这就是Dinic算法的思想
82         {
83             int d = dfs(now.v, t, min(f, now.c - now.f));
84             if(d > 0)
85             {
86                 now.f += d;//正向边流量加d
87                 e[G[u][v] ^ 1].f -= d;
88     //反向边减d，此处在存储边的时候两条反向边可以通过^操作直接找到
89                 return d;
90             }
91         }
92     }
93     return 0;
94 }
95 int Maxflow(int s, int t)
96 {
97     int flow = 0;
98     for(;;)
99     {
100         BFS(s);
101         if(level[t] < 0)return flow;//残余网络中到达不了t，增广路不存在
102         memset(iter, 0, sizeof(iter));//清空当前弧数组
103         int f;//记录增广路的可增加的流量
104         while((f = dfs(s, t, INF)) > 0)
105         {
106             flow += f;
107         }
108     }
109     return flow;
110 }
111 struct node
112 {
113     int x, y;
114     node(){}
115     node(int x, int y):x(x), y(y){}
116     bool operator < (const node& a)const
117     {
118         return x < a.x || x == a.x && y < a.y;
119     }
120 };
121 map<node, int>ID;
122 char Map[30][30];
123 int main()
124 {
125     int n, m, d;
126     scanf("%d%d%d", &n, &m, &d);
127     int tot = 0;
128     for(int i = 0; i < n; i++)
129     {
130         scanf("%s", Map[i]);
131         for(int j = 0; j < m; j++)
132         {
133             if(Map[i][j] != '0')
134             {
135                 ID[node(i, j)] = ++tot;
136                 addedge(tot, tot + 500, Map[i][j] - '0');
137                 if(i < d || j < d || n - i <= d || m - j <= d)
138                     addedge(tot + 500, 0, INF);
139             }
140         }
141     }
142     for(int i = 0; i < n; i++)
143     {
144         for(int j = 0; j < m; j++)
145         {
146             if(Map[i][j] != '0')
147             for(int x = -d; x <= d; x++)
148             {
149                 for(int y = -d; y <= d; y++)
150                 {
151                     int xx = x + i;
152                     int yy = y + j;
153                     if(xx >= 0 && xx < n && yy >= 0 && yy < m && (xx != i || yy != j) && Map[xx][yy] != '0')
154                     {
155                         if(abs(i - xx) + abs(j - yy) <= d)addedge(ID[node(i, j)] + 500, ID[node(xx, yy)], INF);
156                     }
157                 }
158             }
159         }
160     }
161     int cnt = 0;
162     for(int i = 0; i < n; i++)
163     {
164         scanf("%s", Map[i]);
165         for(int j = 0; j < m; j++)if(Map[i][j] == 'L')
166         {
173 }