#include<iostream> #include<sstream> #include<string> #include<vector> #include<list> #include<set> #include<map> #include<stack> #include<queue> #include<algorithm> #include<numeric> #include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #pragma warning(disable:4996) using std::cin; using std::cout; using std::endl; using std::stringstream; using std::string; using std::vector; using std::list; using std::pair; using std::set; using std::multiset; using std::map; using std::multimap; using std::stack; using std::queue; using std::priority_queue; const int MaxVexNum = 2000; const int INF = 1000000000; class Edge { public: int to, capacity, flow; Edge(int t, int c, int f) { to = t,capacity = c,flow = f; } }; vector<pair<int, int>>direction{ {0,-1},{0,1},{1,0},{-1,0} }; class Network { private: int vexnum, edgenum, source, destination,maxflow; vector<vector<Edge>>adjList; public: void addEdge(int from, int to, int cap) { adjList[from].push_back({ to, cap, (int)adjList[to].size() }); adjList[to].push_back({ from, 0, (int)adjList[from].size() - 1 }); } Network() { adjList.resize(MaxVexNum); int row, column, people; cin >> row >> column >> people; source = 0, destination = 2 * row*column + 1; vector<vector<char>>graph(row+1,(vector<char>)(column+1)); for (int i = 1; i <= row; i++) { for (int j = 1; j <= column; j++) { cin >> graph[i][j]; } } for (int i = 1; i <= row; i++) { for (int j = 1; j <= column; j++) { auto first = (i - 1)*column + j; auto second = first + row*column; switch (graph[i][j]) { case '*':addEdge(source,first,1); addEdge(first, second, 1); break; case '.':addEdge(first, second, 1); break; case '@':addEdge(first, second, INF); break; case '#':addEdge(second, destination, people); addEdge(first, second, INF); break; default:break; } for (int k = 0; k < 4; k++) { int x = i + direction[k].first, y = j + direction[k].second; if (x >= 1 && x <= row&&y >= 1 && y <= column) { auto FIRST = (x - 1)*column + y; switch (graph[x][y]) { case '*':addEdge(second, FIRST, 1);break; case '.':addEdge(second, FIRST, 1); break; case '@':addEdge(second, FIRST, INF); break; case '#':addEdge(second, FIRST, INF); break; default:break; } } } } } } int dfs(int src, int sink, int flow,vector<bool>&used) { if (src == sink) { return flow; } used[src] = true; for (int i = 0; i<adjList[src].size(); i++) { Edge &edge = adjList[src][i]; if (!used[edge.to] && edge.capacity>0) { int minflow = dfs(edge.to, sink, std::min(flow, edge.capacity),used); if (minflow>0) { edge.capacity -= minflow; adjList[edge.to][edge.flow].capacity += minflow; return minflow; } } } return 0; } void getMaxFlow() { maxflow = 0; while (1) { vector<bool>used(MaxVexNum); int f = dfs(source, destination, INF,used); if (!f) { return; } maxflow += f; } } void print() { cout << maxflow << endl; } }; int main() { //freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); char ch; while ((ch=cin.get())!=EOF) { ungetc(ch,stdin); Network network; network.getMaxFlow(); network.print(); cin.get(); } return 0; }