题目链接:点击跳转
这题dfs和bfs都可以解决,这里就结合一下,把问题转化为网络流,用dinic算法解决。
对于每个非*的点,都向四周所能到达的地方建一条流量为1的边,如果最后T点有流量能到达,则说明S能到达T点。
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int MAXN = 5e3 + 5e2;
const int INF = 0x3f3f3f3f;
#define endl '\n'
inline void IO_STREAM() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
}
struct Edge{
int to,val,nxt;
}e[MAXN];
int head[MAXN], deep[MAXN], to[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
int n, m, s, t, cnt;
ll res;
char gra[25][25];
inline void init() {
memset(head, -1, sizeof(head));
cnt = 0;
res = 0;
}
inline void add(int from, int to, int val) {
e[cnt] = Edge{to, val, head[from]};
head[from] = cnt++;
}
inline bool check(int x, int y) {
if (x >= 0 && x < n && y >= 0 && y < m) return true;
return false;
}
inline void addPath(int x, int y) {
for (int i = 0; i < 4; i++) {
int xx = x + to[i][0];
int yy = y + to[i][1];
if (check(xx, yy) && gra[xx][yy] != '*') {
add(xx * m + yy, x * m + y, 1);
add(x * m + y, xx * m + yy, 0);
}
}
}
inline bool bfs() {
memset(deep, -1, sizeof(deep));
deep[s] = 1;
queue<int>q;
q.push(s);
while (!q.empty()) {
int front = q.front();
q.pop();
for (int i = head[front]; i != -1; i = e[i].nxt) {
if (deep[e[i].to] == -1 && e[i].val) {
deep[e[i].to] = deep[front] + 1;
q.push(e[i].to);
}
}
}
return (deep[t] != -1);
}
inline int dfs(int x, int totFlow) {
if (x == t || totFlow ==0) return totFlow;
int ans = totFlow;
for (int i = head[x]; i != -1; i = e[i].nxt) {
if (deep[e[i].to] == deep[x] + 1 && e[i].val) {
int flow = dfs(e[i].to, min(totFlow, e[i].val));
e[i].val -= flow;
e[i ^ 1].val += flow;
totFlow -= flow;
if (totFlow == 0) return ans;
}
}
return ans - totFlow;
}
inline void dinic() {
while (bfs()) {
res += dfs(s, INF);
}
}
int main() {
IO_STREAM();
while (cin >> n >> m) {
init();
s = 0, t = n * m + 5;
for (int i = 0; i < n; i++) {
cin >> gra[i];
for (int j = 0; j < m; j++) {
if (gra[i][j] == 'S') {
s = i * m + j;
} else if (gra[i][j] == 'T') {
t = i * m + j;
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (gra[i][j] != '*')
addPath(i, j);
}
}
dinic();
if (res != 0) cout << "yes" << endl;
else cout << "no" << endl;
// cout.flush();
}
return 0;
}