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

题目原文:

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.
在这里插入图片描述

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

在这里插入图片描述

题意

对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();
	}
}
发布了37 篇原创文章 · 获赞 1 · 访问量 1327

猜你喜欢

转载自blog.csdn.net/qq_34727886/article/details/104238478