Sobre el tipo topológico de la teoría de grafos

Prefacio:

Hablando de clasificación topológica, la primera idea es determinar si hay anillos en un gráfico.

El segundo es su pensamiento:

1. Cuenta los grados de pulgada de todos los vértices.

2. Genere el vértice con un grado de entrada de 0 y, al mismo tiempo, se borran todos los bordes con este vértice como punto de inicio, es decir, el grado de entrada del nodo final de este borde es -1 (almacenamiento en cola)

3. Si se generan todos los vértices, significa que el gráfico no tiene bucles; de lo contrario, hay bucles.

Echemos un vistazo a su proceso de implementación específico:

Hmm, ¿tienes cierta comprensión del tipo topológico después de leer lo anterior?

A continuación, mire la aplicación:

En primer lugar, para el nodo del gráfico, si es entero, ¡enhorabuena! Puede usar directamente inDegree [] para contar en grados

Pero ¿qué pasa con String? La respuesta es la conversión de mapas HashMap <String, Integer>

En segundo lugar, ¿existen requisitos para la salida de vértices con grado 0?

Sin cola

Tiene PriorityQueue (cola de prioridad)

Primero mira un fragmento de código Cola ordinaria

static void topologicalSort(HashMap<String,Integer> map,ArrayList<Integer>edge[],int inDegree[],ArrayList<Integer> list,int count)
	{
		Queue<Integer>q=new LinkedList<Integer>();
		Iterator<String> iterator=map.keySet().iterator();
		while(iterator.hasNext())
		{
			String key=iterator.next();
			if(inDegree[map.get(key)]==0)//找到入度为0的点压入队列
				q.add(map.get(key));
		}
		while(!q.isEmpty())
		{
			int now=q.poll();
			list.add(now);//输出入度为0的点
			for(int i=0;i<edge[now].size();i++)
        //把由此节点发出的所有边消除,即边的终点入度减一
			{
				inDegree[edge[now].get(i)]--;
				if(inDegree[edge[now].get(i)]==0)//如果上次操作产生了入度为0的顶点,压入队列
					q.add(edge[now].get(i));
			}
		}
		if(list.size()!=count)
		{
			System.out.println("Error:存在环!");
			return;
		}
		System.out.println();
		for(int i=0;i<list.size();i++)
		{
			if(i==0)
				System.out.print(intToString(list.get(i),map));
			else
				System.out.print(" "+intToString(list.get(i),map));
		}
		//System.out.println();
	}

En segundo lugar, la cola de prioridad (aquí solo se da su uso. Para la implementación de una clasificación topológica específica, puede consultar el código anterior, que es básicamente el mismo y no se detallará aquí):

//这里只写一下优先队列的用法,即通过类继承Comparable接口,覆盖CompareTo方法使类可自比
//PriorityQueue<class> pq  就实现了PriorityQueue中元素的排序。默认从小到大 
class Person implements Comparable<Person>{
    public int age;   
    Person(int age){
    this.age=age;
    }
    public int compareTo(Person other){
        
        return other.age-age;//从大到小
    
    }
    
}
public class Main {
 
    public static void main (String[] args) {
        PriorityQueue<Person> q=new PriorityQueue<Person>();
        Person a=new Person(10);
         Person b=new Person(20);
        q.offer(a);
        q.offer(b);
        System.out.println(q.peek().age);
    }
 
}

Finalmente, publique un problema clásico de clasificación de topología de copa de puente azul:

Descripción del problema
Quién y Dumo piden su amor y regresan solo al sol poniente, la espada ruge, el viento del oeste quiere dejar la primavera en el
fin del mundo, no hay retorno, y hay innumerables explicaciones del éxtasis de los débiles y el polvo primaveral
... .
a plena voz Calle Wolf literatura letal, los cuatro bauhinia que viven cerca y lejos, Edificio 2 202B de cada uno de los diferentes compañeros de piso han recordado sus altibajos en el pasado, y en las largas Hierbas, las flores han o La situación actual de Gu expresó sus opiniones.
XX P: "... comencé a aprender en la escuela primaria ... Sus padres dijeron que estaba bien, pero ... hoy me comuniqué con Beilin nuevamente ..."
XX: "... Casi se convirtió, Terminé en la escuela ... ¡Fui a usar este método con mi compañero de escritorio durante las vacaciones! ... "
W:" ... "(Miles de palabras no son una palabra, hay muchas historias esperando la arqueología)
Z: "... Para venir a Tsinghua ... tenemos una estética diferente, no vamos a agarrar ..."
...
Kalewolf ha recopilado información dispersa sobre sus novias anteriores en esta inmortal charla nocturna. Para obligar a alguien a entregar el proceso de licitación para su tema, ahora Karlwolf necesita un programa que pueda integrar esta información dispersa. Acompañado por la música majestuosa, eufemística y conmovedora, ¡estás aquí como programador (superchica)! Callerwolf está haciendo como Orz para ti y suplicando: "Vaca sagrada ~ Por favor, dame un programa ~ Ou Mi Hair ~" . .
Formato de entrada La
primera línea es un número entero T no mayor de 5, que indica el número de grupos de datos. Después de eso, una fila de cada grupo de datos es un número entero n que no excede 100. Cada una de las siguientes n líneas tiene dos cadenas separadas por un solo espacio (cada cadena tiene solo letras mayúsculas y minúsculas en inglés, y la longitud no excede 10), que son nombres mm de dos dígitos. El primer mm de cada línea se convierte en la novia de alguien antes del segundo mm.
Aquí pretendemos maldecir que alguien no será empapado por dos o más mms al mismo tiempo, y un mm no comerá hierba después de abandonar a alguien. Al mismo tiempo, la profunda percepción de Kallwoff le permite recolectar suficiente Información para determinar el orden de la novia de alguien.
No hay más de 13 caracteres en el pequeño grupo de datos. El
formato de salida es para
generar T líneas, cada línea corresponde a un conjunto de datos, y sus nombres se muestran en el orden en que mms se convierte en la novia de alguien del primero al último, con un espacio entre cada nombre. Separar.
Entrada de muestra
2
2
RY Desconocido
YSZ RY
3
mañana ayer
hoy mañana hoy
hoy Salida de
muestra
YSZ RY Desconocido
mañana hoy ayer

el código se muestra a continuación:



import java.io.*;
import java.util.*;

/*
//example:2 
2 
RY Unknown 
YSZ RY 
3 
tomorrow yestoday 
tomorrow today 
today yestoday 
*/
public class Main {

	static ArrayList<Integer> list=new ArrayList<Integer>();//存放结果
	static ArrayList<Integer>edge[]=new ArrayList[105];//存放每个顶点对应的边
	static HashMap<String,Integer> map=new HashMap<String,Integer>();
//实现string与整数标号的转换
	static int inDegree[]=new int[105];//入度
	
	static void init()//初始化
	{
		list.clear();
		map.clear();
		for(int i=0;i<105;i++)
			edge[i] = new ArrayList<Integer>();
		Arrays.fill(inDegree, 0);
	}
	static String intToString(int i,HashMap<String,Integer> map)
//最后将整数标号转化为对应的值
	{
		Iterator<String> iterator=map.keySet().iterator();
		while(iterator.hasNext())
		{
			String key=iterator.next();
			if(map.get(key)==i)
				return key;
		}
		return null;
	}
	//拓扑排序
	static void topologicalSort(HashMap<String,Integer> map,ArrayList<Integer>edge[],int inDegree[],ArrayList<Integer> list,int count)
	{
		Queue<Integer>q=new LinkedList<Integer>();
		Iterator<String> iterator=map.keySet().iterator();
		while(iterator.hasNext())
		{
			String key=iterator.next();
			if(inDegree[map.get(key)]==0)//找到入度为0的点压入队列
				q.add(map.get(key));
		}
		while(!q.isEmpty())
		{
			int now=q.poll();
			list.add(now);//输出入度为0的点
			for(int i=0;i<edge[now].size();i++)
//把由此节点发出的所有边消除,即边的终点入度减一
			{
				inDegree[edge[now].get(i)]--;
				if(inDegree[edge[now].get(i)]==0)//如果上次操作产生了入度为0的顶点,压入队列
					q.add(edge[now].get(i));
			}
		}
		if(list.size()!=count)
		{
			System.out.println("Error:存在环!");
			return;
		}
		System.out.println();
		for(int i=0;i<list.size();i++)
		{
			if(i==0)
				System.out.print(intToString(list.get(i),map));
			else
				System.out.print(" "+intToString(list.get(i),map));
		}
		//System.out.println();
	}
	
	public static void main(String[] args) throws IOException {
	BufferedReader bfr=new BufferedReader(new InputStreamReader(System.in));
	String str=bfr.readLine();
	String s[]=str.split(" ");
	int n=Integer.parseInt(s[0]);
	for(int i=0;i<n;i++)
	{
		str=bfr.readLine();
		s=str.split(" ");
		int m=Integer.parseInt(s[0]);
		init();
		int count=0;
		for(int j=0;j<m;j++)
		{
			str=bfr.readLine();
			s=str.split(" ");
			String first=s[0];
			String second=s[1];
			//每个字符串对应一个整数代号
			//System.out.println(first+" "+second);
			if(!map.containsKey(first))
				map.put(first, count++);
			if(!map.containsKey(second))
				map.put(second, count++);
			
			inDegree[map.get(second)]++;//second 入度加1
			edge[map.get(first)].add(map.get(second));
		}
		
		topologicalSort(map,edge,inDegree,list,count);
	}

	}

}

emmm, en general, la ordenación topológica sigue siendo muy simple, la estructura de datos que requiere es: una matriz en grados, un conjunto de bordes de vértices y otras cosas no son gran cosa.

Supongo que te gusta

Origin blog.csdn.net/Look_star/article/details/90449957
Recomendado
Clasificación