Dominator UVA - 11902
题目链接
题意
如果有一个点 \(b\) ,从 \(1\) (我喜欢从 \(1\) 开始编号)到 \(b\) 的路径(不一定是最短路径)必须要经过点 \(a\) ,那么答案数组 \(ans[a][b] = Y\) ,否则 \(ans[a][b] = N\)
输出 \(ans\) 数组。
思路
如果把一个点 \(a\) 删掉后有几个原来能从 \(1\) 走到的点 \(y_1,y_2,...,y_k\) 不能从 \(1\) 走到了,那么从 \(1\) 到这几个点的路径一定要经过点 \(a\) 即 \(ans[a][y_1] = ans[a][y_2] = ... = ans[a][y_k] = Y\)
代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 110;
int test_case = 1;
int n;
bool g[N][N],backup_g[N][N];
bool vis[N],backup_vis[N];
bool ans[N][N];
void dfs (int x) {
if (vis[x]) return ;
vis[x] = true;
for (int i = 1;i <= n;i++) {
if (g[x][i] && !vis[i]) dfs (i);
}
}
int main () {
int T;
cin >> T;
while (T--) {
cin >> n;
for (int i = 1;i <= n;i++) {
for (int j = 1;j <= n;j++) {
cin >> g[i][j];
backup_g[i][j] = g[i][j];
}
}
memset (vis,false,sizeof (vis));
dfs (1);
memcpy (backup_vis,vis,sizeof (vis));
memset (ans,false,sizeof (ans));
for (int i = 1;i <= n;i++) {
if (vis[i]) ans[1][i] = ans[i][i] = true;
}
for (int i = 2;i <= n;i++) {
memset (g[i],false,sizeof (g[i]));
memset (vis,false,sizeof (vis));
dfs (1);
for (int j = 1;j <= n;j++) {
if (!vis[j] && backup_vis[j]) ans[i][j] = true;
}
memcpy (g[i],backup_g[i],sizeof (backup_g[i]));
}
cout << "Case " << test_case++ << ":" << endl;
for (int i = 1;i <= 2 * n + 1;i++) {
if (i & 1) {
cout << "+";
for (int j = 2;j <= 2 * n;j++) cout << "-";
cout << "+";
}
else {
for (int j = 1;j <= 2 * n + 1;j++) {
if (j & 1) cout << "|";
else {
if (ans[i / 2][j / 2]) cout << "Y";
else cout << "N";
}
}
}
cout << endl;
}
}
return 0;
}

浙公网安备 33010602011771号