当前位置: 代码迷 >> 综合 >> ACM Plan UVa - 11902 Dominator(图的遍历,深度优先)
  详细解决方案

ACM Plan UVa - 11902 Dominator(图的遍历,深度优先)

热度:59   发布时间:2023-10-15 12:30:04.0

题目原文:

In graph theory, a node X dominates a node Y if every path from the predefined start node to Y must go through X. If Y is not reachable from the start node then node Y does not have any dominator. By definition, every node reachable from the start node dominates itself. In this problem, you will be given a directed graph and you have to find the dominators of everynode where the 0-th node is the start node. Asanexample,for the graph shown right,3 dominates 4 since all the paths from 0 to 4 must pass through 3. 1 doesn’t dominate 3 since there is a path 0-2-3 that doesn’t include 1.
ACM Plan UVa - 11902 Dominator(图的遍历,深度优先)

Input

The first line of input will contain T (≤ 100) denoting the number of cases. Each case starts with an integer N (0 < N < 100) that represents the number of nodes in the graph. The next N lines contain N integers each. If the j-th (0 based) integer of i-th (0 based) line is ‘1’, it means that there is an edge from node i to node j and similarly a ‘0’ means there is no edge.

Output

For each case, output the case number first. Then output 2N +1 lines that summarizes the dominator relationship between every pair of nodes. If node A dominates node B, output ‘Y’ in cell (A,B), otherwise output ‘N’. Cell (A,B) means cell at A-th row and B-th column. Surround the output with ‘|’, ‘+’ and ‘-’ to make it more legible. Look at the samples for exact format.

Sample Input

2
5
0 1 1 0 0
0 0 0 1 0
0 0 0 1 0
0 0 0 0 1
0 0 0 0 0
1
1

Sample Output

ACM Plan UVa - 11902 Dominator(图的遍历,深度优先)

题意

对0到n-1个点,求出每个点的支配点,即从0开始必须经过 i 点才能到达的点,输出所有的点的情况。特殊情况:0也是0的支配点之一。

貌似可以用割点的方法求出来,但这是一道简单题,应该尽量让代码简洁一点。

思路

采用深度优先,对每个点,先将该点暂时标记,使得深搜进入不了该点,而后对0点进行深搜,记录到达的点的情况。

而后,从1开始到n-1,将每个点的搜索结果与0点的搜索结果一一异或,便可得到最终结果。

原理就是,去除某点后的遍历情况如果有和0点一样的,说明不通过该点也能到达那种情况,存在其他路径。只有不一样的情况才算是独有路径。

代码

#include <cstdio>
#include <cstring>
int g[110][110];
int visit[110][110];
int book[110];
int n;
void dfs(int x){
    book[x] = 1;for(int i = 0; i < n; i++){
    if(book[i] == 0 && g[x][i] == 1)dfs(i);}
}
void prow(){
    putchar('+');for(int i = 0; i < n * 2 - 1; i++)putchar('-');puts("+");
}
int main(){
    // freopen("i.txt", "r", stdin);// freopen("o.txt", "w", stdout);int t, c = 1; scanf("%d", &t);while(t--){
    scanf("%d", &n);for(int i = 0; i < n; i++)for(int j = 0; j < n; j++)scanf("%d", &g[i][j]);for(int i = 0; i < n; i++){
    memset(book, 0, sizeof(book));book[i] = -1;//暂时去除该点dfs(0);book[i] = 0;for(int j = 0; j < n; j++)visit[i][j] = book[j];}visit[0][0] = 1;//记得将特殊情况补上for(int i = 1; i < n; i++)for(int j = 0; j < n; j++)visit[i][j] ^= visit[0][j];//异或printf("Case %d:\n", c++);for(int i = 0; i < n; i++){
    prow();putchar('|');for(int j = 0; j < n; j++)printf("%c|", visit[i][j] == 1 ? 'Y' : 'N');puts("");}prow();}
}
  相关解决方案