拓扑排序及关键路径

拓扑排序的实现:

辅助数组:

  • int Indegree[100]:用来存放各结点的前驱结点个数
  • tops[10]:用来存放排序后的顺序
    因为需要计算每个结点的入度和出度,所以用了十字链表。

过程

  • 计算每个结点的前驱结点个数,记录到indegree中;
  • 让前驱结点个数为零的结点入栈;
  • 当栈不为空时,输出栈顶结点,加入到tops中。遍历所有以,次结点,为尾结点的结点,让这些结点的入度减一,如果这个结点的入度为零,就加入栈中;
#include
#include
using namespace std;
struct Node
{
    int from;
    int to;
    Node * head_same;
    Node * tail_same;
};
struct First_Node
{
    string name;
    Node * in_node;
    Node * out_node;
};
struct Graph
{
    int Vex_num, Edge_num;
    First_Node * Arr;
};
int Get_Location(Graph T, string name)
{
    for(int i = 1; i <= T.Vex_num; i++)
    {
        if(T.Arr[i].name == name)
            return i;
    }
    return -1;
}
void Create_Graph(Graph & T)
{
    cin>>T.Vex_num>>T.Edge_num;
    T.Arr = new First_Node[T.Vex_num + 1];
    for(int i = 1; i <= T.Vex_num; i++)
    {
        cin>>T.Arr[i].name;
        T.Arr[i].in_node = nullptr;
        T.Arr[i].out_node = nullptr;
    }
    int x, y; string n1, n2;
    for(int i = 1; i <= T.Edge_num; i++)
    {
        cin>>n1>>n2;
        x = Get_Location(T,n1);
        y = Get_Location(T,n2);
        Node * s = new Node;
        s->from = x;s->to = y;
        s->head_same = T.Arr[y].in_node;
        T.Arr[y].in_node = s;
        s->tail_same = T.Arr[x].out_node;
        T.Arr[x].out_node = s;
    }
}
void Find_Indegree(Graph T,int Indegree[])
{
    for(int i = 1; i <= T.Vex_num; i++)
    {
        int num = 0;
        Node * s = T.Arr[i].in_node;
        while(s != nullptr)
        {
            num++;
            s = s->head_same;
        }
        Indegree[i] = num;
    }
}
void Topo_Sort(Graph T)
{
    int Indegree[10];
    Find_Indegree(T,Indegree);
    stack<int> S;
    for(int i = 1; i <= T.Vex_num; i++)
    {
        if(Indegree[i] == 0)
            S.push(i);
    }
    int m = 1, tops[10];
    while(!S.empty())
    {
        int k = S.top();S.pop();
        tops[m] = k;
        m++;
        Node * s = T.Arr[k].out_node;
        while(s != nullptr)
        {
            k = s->to;
            Indegree[k]--;
            if(Indegree[k] == 0)
                S.push(k);
            s = s->tail_same;
        }
    }
    if(m - 1 == T.Vex_num)
    {
        for(int i = 1; i <= T.Vex_num; i++)
            cout<<tops[i]<<"\t";
    }else{
        cout<<0;
    }
}
int main()
{
    Graph T;
    Create_Graph(T);
    Topo_Sort(T);
}
/*
6 8
v1 v2 v3 v4 v5 v6
v1 v6
v1 v5
v1 v3
v2 v3
v3 v4
v4 v6
v5 v6
v5 v4
*/

关键路径

#include
#include
#include
using namespace std;
struct Node
{
    int from;
    int to;
    Node * head_same;
    Node * tail_same;
    int time;
};
struct First_Node
{
    string name;
    Node * in_node;
    Node * out_node;
};
struct Graph
{
    int Vex_num, Edge_num;
    First_Node * Arr;
};
int Get_Location(Graph T, string name)
{
    for(int i = 1; i <= T.Vex_num; i++)
    {
        if(T.Arr[i].name == name)
            return i;
    }
    return -1;
}
void Create_Graph(Graph & T)
{
    cin>>T.Vex_num>>T.Edge_num;
    T.Arr = new First_Node[T.Vex_num + 1];
    for(int i = 1; i <= T.Vex_num; i++)
    {
        cin>>T.Arr[i].name;
        T.Arr[i].in_node = nullptr;
        T.Arr[i].out_node = nullptr;
    }
    int x, y, time; string n1, n2;
    for(int i = 1; i <= T.Edge_num; i++)
    {
        cin>>n1>>n2>>time;
        x = Get_Location(T,n1);
        y = Get_Location(T,n2);
        Node * s = new Node;
        s->from = x;s->to = y;
        s->head_same = T.Arr[y].in_node;
        T.Arr[y].in_node = s;
        s->tail_same = T.Arr[x].out_node;
        T.Arr[x].out_node = s;
        s->time = time;
    }
}
bool Topo_Sort(Graph T,int topo[])
{
    int Indegree[10];
    for(int i = 1; i <= T.Vex_num; i++)
    {
        int num = 0;
        Node * s = T.Arr[i].in_node;
        while(s != nullptr)
        {
            num++;
            s = s->head_same;
        }
        Indegree[i] = num;
    }
    int m = 1;stack<int> S;
    for(int i = 1; i <= T.Vex_num; i++)
        if(Indegree[i] == 0) S.push(i);
    while(!S.empty())
    {
        int k = S.top();S.pop();
        topo[m] = k;m++;
        Node * s = T.Arr[k].out_node;
        while(s != nullptr)
        {
            int j = s->to;
            Indegree[j]--;
            if(Indegree[j] == 0)
                S.push(j);
            s = s->tail_same;
        }
    }
    if(m - 1 != T.Vex_num)
        return 0;
    else
        return 1;
}
void CriticalPath(Graph T)
{
    int topo[10];
    if(!Topo_Sort(T,topo))
        return;
    int ve[10],vl[10];
    memset(ve,0,sizeof(ve));
    for(int i = 1; i <= T.Vex_num; i++)
    {
        Node * s = T.Arr[topo[i]].out_node;
        while(s != nullptr)
        {
            if(ve[topo[i]] + s->time > ve[s->to])
                ve[s->to] = ve[topo[i]] + s->time;
            s = s->tail_same;
        }
    }
    for(int i = 1; i <= T.Vex_num; i++)
        vl[i] = ve[T.Vex_num];
    for(int i = T.Vex_num; i >= 1; i--)
    {
        Node * s = T.Arr[topo[i]].in_node;
        while(s != nullptr)
        {
            if(vl[s->from] > vl[s->to] - s->time)
                vl[s->from] = vl[s->to] - s->time;
            s = s->head_same;
        }
    }
    for(int i = 1; i <= T.Vex_num; i++)
    {
        Node * s = T.Arr[i].out_node;
        int e, l;
        while(s != nullptr)
        {
            e = ve[i];
            l = vl[s->to] - s->time;
            if(e == l)
                cout<<T.Arr[i].name<<"\t"<<T.Arr[s->to].name<<endl;
            s = s->tail_same;
        }
    }
}
int main()
{
    Graph T;
    Create_Graph(T);
    CriticalPath(T);
}
/*
9 11
v1 v2 v3 v4 v5 v6 v7 v8 v9
v1 v2 6
v1 v3 4
v1 v4 5
v2 v5 1
v3 v5 1
v5 v7 9
v5 v8 7
v7 v9 2
v8 v9 4
v4 v6 2
v6 v8 4
*/

你可能感兴趣的:(数据结构)