ν‹°μŠ€ν† λ¦¬ λ·°

- λ°©ν–₯κ·Έλž˜ν”„ G

- λ°©ν–₯ 비싸이클 κ·Έλž˜ν”„(directed acyclic graph: DAG)λ©΄ μœ„μƒμˆœμ„œ(topologicalorder)λ₯Ό ꡬ해 인쇄

- G에 λ°©ν–₯ 싸이클(directed cycle)이 μ‘΄μž¬ν•˜λ©΄ μœ„μƒμˆœμ„œλ₯Ό ꡬ할 수 μ—†μœΌλ―€λ‘œ 0을 인쇄

- μΈμ ‘λ¦¬μŠ€νŠΈ ꡬ쑰둜 ν‘œν˜„ && λ°°μ—΄λ‘œ κ΅¬ν˜„

- in-degree (μ§„μž…μ°¨μˆ˜) μ΄μš©ν•΄μ„œ μœ„μƒμˆœμ„œ κ΅¬ν•˜κΈ°

- μœ„μƒμˆœμ„œλ₯Ό κ΅¬ν•˜λŠ” κ³Όμ •μ—μ„œ λ°©ν–₯μ‹Έμ΄ν΄μ˜ 쑴재 μ—¬λΆ€ 확인

- κ·Έλž˜ν”„μ— λŒ€ν•œ μœ„μƒμˆœμ„œλŠ” μ—¬λŸ¬ 개 μžˆμ„ 수 μžˆμ§€λ§Œ, μ•„λž˜ μ½”λ“œμ—μ„œλŠ” 단 ν•œ 개의 μœ„μƒμˆœμ„œλ§Œ 좜λ ₯ κ°€λŠ₯ν•˜λ„λ‘

 

 

# include <stdio.h>
# include <stdlib.h>
# pragma warning(disable:4996)

int n, m;
int* in;
int* topOrder;
int* queue;
int queueSize = -1;

int queueIsEmpty() {
	if (queueSize == -1)
		return 1;
	else
		return 0;
}

void enQueue(int data) {
	queueSize++;
	queue[queueSize] = data;
}

int deQueue() {
	if (queueIsEmpty())
		return -1;

	int tmp = queue[0];
	for (int i = 0; i < queueSize; i++)
		queue[i] = queue[i + 1];

	queueSize--;
	return tmp;
}


typedef struct node {
	int elem;
	struct node* next;
}NODE;

typedef struct edge {
	int origin;
	int destination;
}EDGE;

typedef struct vertex {
	char name;
	int inDegree;
	struct node* outEdges;
	struct node* inEdges;
}VERTEX;

NODE* getNode() {
	NODE* newNode = (NODE*)malloc(sizeof(NODE));
	newNode->next = NULL;
	return newNode;
}

struct graph {
	VERTEX vertices[100];
	EDGE edges[1000];
}G;// λ°©ν–₯κ·Έλž˜ν”„

int findindex(char vname) {
	for (int i = 0; i < n; i++) {
		if (G.vertices[i].name == vname)
			return i;
	}
	return -1;
}

void insertFisrt(NODE* H, int i) {
	NODE* newNode = getNode();
	newNode->elem = i;
	newNode->next = H->next;
	H->next = newNode;
	return;
}

void insertVertex(char vname, int i) {
	G.vertices[i].name = vname;
	G.vertices[i].inDegree = 0;
	G.vertices[i].inEdges = getNode();
	G.vertices[i].outEdges = getNode();
}

void insertDirectedEdge(char uname, char wname, int i) {
	int u = findindex(uname);
	int w = findindex(wname);

	G.edges[i].origin = u;
	G.edges[i].destination = w;

	insertFisrt(G.vertices[u].outEdges, i);
	insertFisrt(G.vertices[w].inEdges, i);

	G.vertices[w].inDegree++;
	return;
}

void buildGraph() {

	scanf("%d", &n);
	getchar();
	topOrder = (int*)malloc(sizeof(int) * (n + 1));
	queue = (int*)malloc(sizeof(int) * n);
	in = (int*)malloc(sizeof(int) * n);

	char vname;
	for (int i = 0; i < n; i++) {
		scanf("%c", &vname);
		insertVertex(vname, i);
		getchar();
	}

	scanf("%d", &m);
	getchar();

	char uname, wname;
	for (int i = 0; i < m; i++) {
		scanf("%c %c", &uname, &wname);
		getchar();
		insertDirectedEdge(uname, wname, i);
	}
	return;
}

void topologicalSort() {
	int t = 1;
	int u, w;

	for (int i = 0; i < n; i++)
		queue[i] = 0;

	for (int i = 0; i < n; i++) {
		in[i] = G.vertices[i].inDegree;
		if (in[i] == 0)
			enQueue(i);// in_degreeκ°€ 0이면 큐에 정점 μΆ”κ°€
	}
	while (!queueIsEmpty()) {// 큐가 빌 λ•ŒκΉŒμ§€
		u = deQueue();// 큐의 μ•ž μš”μ†Œλ₯Ό T둜 κ°€μ Έμ™€μ„œ append
		topOrder[t] = u;
		t++;

		NODE* tmp = G.vertices[u].outEdges->next;
		while (tmp != NULL) {// dequeue()ν•œ 정점에 μΈμ ‘ν•œ 정점쀑 λ°©λ¬Έν•˜μ§€ μ•Šμ€ μ •μ μ˜ in_degreeλ₯Ό ν•˜λ‚˜ κ°μ†Œ
			w = G.edges[tmp->elem].destination;
			in[w]--;
			if (in[w] == 0)// in_degree κ°μ†Œ ν›„ 값이 0이면 ν•΄λ‹Ή 정점은 queue에 enqueue() ν•˜κ³  λ°©λ¬Έν•œ κ²ƒμœΌλ‘œ ν‘œμ‹œ
				enQueue(w);
			tmp = tmp->next;
		}
	}
	if (t < n + 1)
		topOrder[0] = 0;
	else
		topOrder[0] = 1;
	return;
}

int main() {

	buildGraph();
	topologicalSort();

	if (topOrder[0] == 0) {
		printf("0\n");
	}
	else {
		for (int i = 1; i <= n; i++)
			printf(" %c", G.vertices[topOrder[i]].name);
	}
	return 0;
}
λ°˜μ‘ν˜•