/*
Name:
Copyright:
Author:
Date:17-11-14 21:02
Description: Sequence of variables for topological sequencing
Suppose there are n variables (1<=n<=26, the variable names are represented by a single lowercase letter), and M two-tuple (U,V), which indicates that the variable u is less than V, respectively. So what should all the variables look like from small to large?
For example, there are 4 variables a,b,c,d, and if A<b,c<b,d<c is known, the ordering of these 4 variables may be a<d<c<b. Although there may be other possibilities, you just need to find one of them.
Input
The input is a string of data that contains n+n characters representing N relationships (1<=n<=100000), such as the sequence "ABCBDC", which represents a<b,c<b,d<c.
Output
Gives a string that stores a sequence of variables that meet the requirements, for example, the string "ADCB" represents a<d<c<b.
*/
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define MAXM 26//Maximum number of variables (vertices)
#define MAXN 100000//maximum relationship Quantity
typedef char Vertextype; Vertex types are custom-defined by the user
typedef int EDGETYPE; The weight type on the edge is custom-defined by the user
typedef struct edgenode{//Benzi node
int Adjvex; adjacency point field, which stores the subscript corresponding to the vertex
// Edgetype weight; For a non-grid diagram, it is not necessary to
struct Edgenode *next; Chain field, pointing to the next adjacency point
} Edgenode;
typedef struct vertexnode{//Vertex table node
Vertextype data; Vertex fields, storing vertex information
int in; Number of storage vertex-in degrees
Edgenode *firstedge; Edge table Header pointer
} Vertexnode;
typedef struct edge{//edge set Array
int u, v; ARC Tail and ARC head
int next; Point to the next edge of the same arc tail
// Edgetype weight; For a non-grid diagram, it is not necessary to
} edgelib;
int BOOK[MAXM] = {0}; Mark if a letter appears
int Istoposeq (char *data, char *topo);//Determines whether the topo string is a topological sequence based on the relational list data
int Creategraph (char *data, Vertexnode *GL);//Create a diagram
void Printgraph (Vertexnode *gl);//output diagram
int Topologicalsort_dfs (char *topo, vertexnode *gl, int n),//topological sort, get topological sequence, return False if ring is present
int Topologicalsort_bfs (char *topo, vertexnode *gl, int n),//topological sort, get topological sequence, return False if ring is present
int creategraph_2 (char *data, int in[], int first[], edgelib edge[]);//Create a diagram
void printgraph_2 (int first[], edgelib edge[]);//output diagram
int Topologicalsort (char *topo, edgelib edge[], int in[], int first[], int n),//topological sort, get topological sequence, return False if ring is present, use queue to store topological sequence
int main ()
{
int i, n;
Vertexnode GL[MAXM];
Char topo[maxm+1];
Char data[maxn+maxn+1];
int IN[MAXM], FIRST[MAXM]; Storing vertex information
Edgelib EDGE[MAXN]; Storage Edge Information
Gets (data);
n = creategraph_2 (data, in, first, edge);//Create a diagram
Printgraph_2 (first, edge);//output diagram
if (Topologicalsort (Topo, Edge, in, first, N))//topology sequence is constructed using topological ordering
Puts (topo);
Else
Puts ("There is no sequence to satisfy the condition");
if (ISTOPOSEQ (data, topo))///based on the relational list data, determine if the topo string is a topological sequence
Puts (topo);
Else
Puts ("There is no sequence to satisfy the condition");
Gets (data);
n = creategraph (data, GL);//Create a diagram
Printgraph (GL);//output diagram
if (ISTOPOSEQ (data, topo))///based on the relational list data, determine if the topo string is a topological sequence
Puts (topo);
Else
Puts ("There is no sequence to satisfy the condition");
if (Topologicalsort_bfs (topo, GL, N))//topology sequence constructed using topological sort
Puts (topo);
Else
Puts ("There is no sequence to satisfy the condition");
Gets (data);
n = creategraph (data, GL);//Create a diagram
Printgraph (GL);//output diagram
if (Topologicalsort_dfs (topo, GL, N))//topology sequence constructed using topological sort
Puts (topo);
Else
Puts ("There is no sequence to satisfy the condition");
if (ISTOPOSEQ (data, topo))///based on the relational list data, determine if the topo string is a topological sequence
Puts (topo);
Else
Puts ("There is no sequence to satisfy the condition");
return 0;
}
/*
Function Name: creategraph
function function: The vertex and edge information is read into the adjacency table of the representation graph
Input variable: Char *data: A string that stores N-relationships
Vertexnode *GL: Array of vertex tables
Output variable: An array of vertex tables representing graphs
return value: Int: number of vertices
*/
int Creategraph (char *data, Vertexnode *GL)
{
int i, u, v;
int count = 0;//record vertex count
Edgenode *e;
for (i=0; i<maxm; i++)//initialization diagram
{
Gl[i].data = i + ' a ';
gl[i].in = 0;
Gl[i].firstedge = NULL;
Book[i] = 0;
}
for (i=0; data[i]!= '; i+=2)//Read two variables at a time
{
U = data[i]-' a '; The letters are converted to numbers, ' a ' corresponds to 0, ' B ' corresponds to 1, and so on
v = data[i+1]-' a ';
Book[u] = book[v] = 1;
E = (edgenode*) malloc (sizeof (Edgenode)); Inserting edge table nodes with head interpolation method
if (!e)
{
Puts ("Error");
Exit (1);
}
E->adjvex = v;
E->next = Gl[u].firstedge;
Gl[u].firstedge = e;
gl[v].in++;
}
for (i=0; i<maxm; i++)//COMPUTE vertex count
{
if (book[i]! = 0)
count++;
}
return count;
}
void Printgraph (Vertexnode *gl)//output diagram
{
int u, v;
Edgenode *e;
for (u=0; u<maxm; u++)
{
printf ("g[%d] =%c:", U, Gl[u].data);
for (E=gl[u].firstedge; e!=null; e=e->next)//Reduce the adjacency point of U by 1 and put the vertex of the 0 into the stack
{
v = e->adjvex;
printf ("<%c,%c>,", Gl[u].data, Gl[v].data);
}
printf ("\ n");
}
printf ("\ n");
}
/*
Function Name: Topologicalsort_dfs
function function: Topological ordering, using depth-first search to get topological sequence
Input variable: Char *topo: String used to store the topological sequence
Vertexnode *GL: Array of vertex tables
int N: Number of vertices
Output variable: The string used to store the topological sequence
return value: Int: Topological sort succeeded return true, False if ring is present
*/
int Topologicalsort_dfs (char *topo, vertexnode *gl, int n)
{
int i, u, V, top;
int count = 0; Number of vertices used for statistical output
Edgenode *e;
int STACK[MAXM];
for (top=i=0; i<maxm; i++)//Enter the vertex of the 0 into the stack
{
if (book[i]! = 0 && gl[i].in = = 0)
{
stack[top++] = i;
}
}
while (Top > 0)//Use depth first search to get topological sequence
{
U = stack[--top];
topo[count++] = U + ' a ';
for (E=gl[u].firstedge; e!=null; e=e->next)//Reduce the adjacency point of U by 1 and put the vertex of the 0 into the stack
{
v = e->adjvex;
if (--gl[v].in = = 0)
stack[top++] = v;
}
}
Topo[count] = ' + ';
return (count = = N), or//if count is less than the number of vertices, indicates that there is a ring
}
/*
Function Name: TOPOLOGICALSORT_BFS
function function: Topological ordering, using breadth-first search to get topological sequence
Input variable: Char *topo: String used to store the topological sequence
Vertexnode *GL: Array of vertex tables
int N: Number of vertices
Output variable: The string used to store the topological sequence
return value: Int: Topological sort succeeded return true, False if ring is present
*/
int Topologicalsort_bfs (char *topo, vertexnode *gl, int n)
{
int i, u, V, front, rear;
Edgenode *e;
Front = rear = 0;
for (i=0; i<maxm; i++)//Enter the vertex of the 0 into the stack
{
if (book[i]! = 0 && gl[i].in = = 0)
{
topo[rear++] = i + ' a ';
}
}
while (front < rear)//Use breadth-first search to get topological sequences
{
U = topo[front++]-' a ';
for (E=gl[u].firstedge; e!=null; e=e->next)//Reduce the adjacency point of U by 1 and put the vertex of the 0 into the stack
{
v = e->adjvex;
if (--gl[v].in = = 0)
topo[rear++] = v + ' a ';
}
}
Topo[rear] = ' + ';
return (rear = = n);//If Count is less than the number of vertices, it indicates that there is a ring
}
/*
Function Name: creategraph_2
function function: read vertex and edge information into the side table set of the presentation graph
Input variable: Char *data: A string that stores N-relationships
int in[]: Stores the entry information for vertices
int first[]: point to the first edge with the vertex as the end of the arc
Edgelib edge[]: Benzi set with edge information stored
Output variables: An array of Benzi sets that represent graphs
return value: Int: number of vertices
*/
int creategraph_2 (char *data, int in[], int first[], edgelib edge[])//Create a diagram
{
int I, J;
int count = 0;//record vertex count
for (i=0; i<maxm; i++)//initialization diagram
{
First[i] =-1;
Book[i] = 0;
In[i] = 0;
}
for (j=i=0; data[i]!= '; i+=2,j++)//Read two variables at a time
{
EDGE[J].U = data[i]-' a '; The letters are converted to numbers, ' a ' corresponds to 0, ' B ' corresponds to 1, and so on
EDGE[J].V = data[i+1]-' a ';
BOOK[EDGE[J].U] = book[edge[j].v] = 1;
Edge[j].next = first[edge[j].u];
FIRST[EDGE[J].U] = j;
in[edge[j].v]++;
}
for (i=0; i<maxm; i++)//COMPUTE vertex count
{
if (book[i]! = 0)
count++;
}
return count;
}
void printgraph_2 (int first[], edgelib edge[])//output diagram
{
int I, J;
for (i=0; i<maxm; i++)
{
printf ("g[%d] =%c:", I, i+ ' a ');
j = First[i]; Point to the first side of I
while (j! =-1)
{
printf ("<%c,%c>,", edge[j].u+ ' a ', edge[j].v+ ' a ');
j = Edge[j].next; Point to next Edge
}
printf ("\ n");
}
printf ("\ n");
}
/*
Function Name: Topologicalsort
function function: Topological ordering, using breadth-first search to get topological sequence
Input variable: Char *topo: String used to store the topological sequence
Edgelib edge[]: Benzi set with edge information stored
int in[]: Stores the entry information for vertices
int first[]: point to the first edge with the vertex as the end of the arc
int N: Number of vertices
Output variable: The string used to store the topological sequence
return value: Int: Topological sort succeeded return true, False if ring is present
*/
int Topologicalsort (char *topo, edgelib edge[], int in[], int first[], int n)
{
int i, u, front, rear;
Front = rear = 0;
for (i=0; i<maxm; i++)//Enter the vertex of the 0 into the stack
{
if (book[i]! = 0 && In[i] = = 0)
{
topo[rear++] = i + ' a ';
}
}
while (front < rear)//Use breadth-first search to get topological sequences
{
U = topo[front++]-' a ';
for (i=first[u]; i!=-1; i=edge[i].next)
{
if (--in[edge[i].v] = = 0)
topo[rear++] = edge[i].v + ' a ';
}
}
Topo[rear] = ' + ';
return (rear = = n);//If Count is less than the number of vertices, it indicates that there is a ring
}
int Istoposeq (char *data, char *topo)//Determines whether the topo string is a topological sequence based on the relational list data
{
int POS[MAXM] = {0};
int i;
for (i=0; topo[i]!= '; i++)//Read variable subscript
Pos[topo[i]-' a '] = i;
for (i=0; data[i]!= '; i+=2)//Read two variables at a time
{
if (pos[data[i]-' a '] > pos[data[i+1]-' a ')
return false;
}
return true;
}
Variable sequence code of topological ordering