poj 1207(拓扑排序用到了深搜)

本文介绍了一种基于深度优先搜索的拓扑排序算法实现过程,该算法通过输入顶点之间的关系来确定一个有序序列,适用于有向无环图。文章详细展示了如何构建顶点关系矩阵并进行递归遍历以找到所有可能的拓扑序列。

奋斗

拓扑排序的思想:
1:从有向图中选一个无前驱的顶点输出;
2:将此顶点和以它为起点的弧删除;
3:重复1和2,直到不存在无前驱的顶点;
4:若此时输出的顶点数小于有向图中的顶点数,则说明有向图中存在回路,否则输出的顶点的顺序即为一个拓扑序列。

package com.liang.poj;

import java.util.Arrays;
import java.util.Scanner;

public class Test1270Tuo_Pu {
	static StringBuffer strb1 = new StringBuffer();
	static int[] count = null;
	static int[][] relation = null;
	static String str1 = "";
	static String str2 = "";
	static char[] result = null;
	static boolean[] visited = null;
	static int[] tag = null;
	static int[][] liang = null;
	static int sum = 0;

	public static void main(String[] args) throws Exception{
		Scanner scan = new Scanner(System.in);

		str1 = scan.nextLine();
		str2 = scan.nextLine();

		for (int i = 0; i < str1.length(); i += 2) {
			strb1.append(str1.charAt(i));
		}

		sum = strb1.length();
		relation = new int[sum][sum];
		count = new int[sum];
		result = new char[sum];
		visited = new boolean[sum];
		Arrays.fill(visited, false);
		tag = new int[sum];
		liang = new int[sum][sum];

		makeSet();
		dfs(0);
	}

	public static void makeSet() {
		for (int i = 0; i < str2.length(); i += 4) {
			int a = 0;
			int b = 0;
			for (int j = 0; j < strb1.length(); j++) {
				if (str2.charAt(i) == strb1.charAt(j)) {
					a = j;
					break;
				}
			}

			for (int j = 0; j < strb1.length(); j++) {
				if (str2.charAt(i + 2) == strb1.charAt(j)) {
					b = j;
					count[j]++;
					break;
				}
			}

			relation[a][b] = 1;
		}
	}

	public static void dfs(int geshu) {
		if (geshu >= sum) {
			show();
			return;
		}
		for (int i = 0; i < count.length; i++) {
			if (count[i] == 0 && !visited[i]) {
				result[geshu] = strb1.charAt(i);
				visited[i] = true;
				for (int j = 0; j < relation.length; j++) {
					if (relation[i][j] != 0) {
						count[j]--;
						tag[j]++;
						liang[i][j] = 1;
					}
				}
				dfs(geshu + 1);
				visited[i] = false;
				for (int j = 0; j < relation.length; j++) {
					if (tag[j] != 0 && liang[i][j] != 0) {
						count[j]++;
						tag[j]--;
						liang[i][j] = 0;
					}
				}
			}
		}
	}

	public static void show() {
		for (int i = 0; i < result.length; i++) {
			System.out.print(result[i]);
		}
		System.out.println();
	}

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值