/**
1.求拓撲排序的序列
2.求關鍵路徑:
廣域網成整個工程所需的時間取決於從源點到匯點的最長路徑長度。
路徑長度等於路徑上各邊的權之和。這條具有最大長度的路徑就叫做關鍵路徑
(拓撲排序可以判斷有向圖是否有環)
(並查集可以判斷無向圖是否有環,若merge(..)的時候,兩個節點已經在同一個連通分支時,則表示有環)
輸入://4 1 3
7 8
1 2 1
1 3 2
1 4 1
2 5 1
3 5 4
4 6 3
5 7 5
6 7 2
**/
#include<iostream>
#include<vector>
#include<list>
#define MAX_N 100
using namespace std;
struct Node
{
int num;
int cost;
};
struct Edge
{
int d;//入度
vector<Node> v;
};
Edge edge[MAX_N];
int n,m;
list<int> ls;
void getTopOrder();
void getKeyRoad();
int main()
{
cin>>n>>m;
Node nod;
for(int i=0;i<=n;i++)
{
edge[i].d=0;
}
for(int i=0;i<m;i++)
{
int a,b,val;
cin>>a>>b>>val;
nod.num=b;
nod.cost=val;
edge[a].v.push_back(nod);
edge[b].d++;
}
getTopOrder();
getKeyRoad();
return 0;
}
void getTopOrder()
{
vector<Node> vt;
int counts=0;
for(int i=1;i<=n;i++)
{
if(edge[i].d==0)
{
counts++;
cout<<i<<" ";
ls.push_back(i);
edge[i].d=-1;
vt=edge[i].v;
for(int j=0;j<vt.size();j++)
{
edge[vt[j].num].d--;
}
i=0;
}
}
if(counts==0)
{
cout<<"圖中有環!"<<endl;
}
}
void getKeyRoad()
{
int e[MAX_N],l[MAX_N];
for(int i=1;i<=n;i++)e[i]=0;
vector<Node> vt;
list<int > l1=ls;
while(!l1.empty())
{
int i=l1.front();
l1.pop_front();
vt=edge[i].v;
for(int j=0;j<vt.size();j++)
{
if(e[vt[j].num]<e[i]+vt[j].cost)
{
e[vt[j].num]=e[i]+vt[j].cost;
}
}
}
l[n]=e[n];
l1=ls;
while(!l1.empty())
{
int i=l1.back();
l1.pop_back();
vt=edge[i].v;
for(int j=0;j<vt.size();j++)
{
if(l[i]>l[vt[j].num]-vt[j].cost)
{
l[i]=l[vt[j].num]-vt[j].cost;
}
}
}
cout<<endl;
for(int i=1;i<=n;i++)cout<<e[i]<<" ";
cout<<endl;
for(int i=1;i<=n;i++)cout<<l[i]<<" ";
//若e[i]和l[i]相等,i就是關鍵路徑上的點
cout<<endl;
for(int i=1;i<=n;i++)
{
if(e[i]==l[i])cout<<i<<" ";
}
}
關鍵路徑的空間復雜度分析