输入样例:
9 12
0 1 6
0 2 4
0 3 5
1 4 1
2 4 1
3 5 2
5 4 0
4 6 9
4 7 7
5 7 4
6 8 2
7 8 4
输出样例:
18
就是直接的拓扑排序
#include<stdio.h>
#include<stdlib.h>
#define MAX 101
#define INF 65536
//邻接表存储
typedef struct sonnode{
int num;
int weight;
struct sonnode*next;
}*pson;
typedef struct vnode{
pson first;
}adj[MAX];
typedef struct Gnode{
adj G;
int nv; //顶点数
int ne; //边数
}*Gp;
//初始化图
void initial(Gp Graph,int n,int m)
{
int i;
for(i=0;i<n;i++)
Graph->G[i].first=NULL;
Graph->nv=n;
Graph->ne=m;
}
void buildgraph(Gp Graph)
{
int i,start,end,weight;
pson son;
for(i=0;i<Graph->ne;i++)
{
scanf("%d %d %d",&start,&end,&weight);
son=(pson)malloc(sizeof(struct sonnode));
son->next=Graph->G[start].first;
son->weight=weight;
son->num=end;
Graph->G[start].first=son;
}
}
int topsort(Gp Graph)
{
int indegree[MAX],count=0,i,j,start=-1,end=-1,earliest=0;
int queue[MAX],etime[MAX];
pson son;
//最短时间初始化为0
for(i=0;i<Graph->nv;i++)
etime[i]=0;
//初始化入度为0
for(i=0;i<Graph->nv;i++)
indegree[i]=0;
//统计入度
for(i=0;i<Graph->nv;i++)
for(son=Graph->G[i].first;son!=NULL;son=son->next)
indegree[son->num]++;
//入度为0的入队列
for(i=0;i<Graph->nv;i++)
if(indegree[i]==0)
queue[++end]=i;
if(end==-1)
return -1;
while(start<end)
{
i=queue[++start];//出队
count++;
for(son=Graph->G[i].first;son!=NULL;son=son->next)
{
//入度全部减一
if(--indegree[son->num]==0)
queue[++end]=son->num;
//如果时间更长则更新
if(etime[i]+son->weight>etime[son->num])
etime[son->num]=etime[i]+son->weight;
}
}
if(count<Graph->nv)
return -1;
for(i=0;i<Graph->nv;i++)
if(etime[i]>earliest)
earliest=etime[i];
return earliest;
}
int main()
{
int N,M,answer;
scanf("%d %d",&N,&M);
Gp Graph=(Gp)malloc(sizeof(struct Gnode));;
initial(Graph,N,M);
buildgraph(Graph);
answer=topsort(Graph);
if(answer==-1)
printf("Impossible");
else
printf("%d",answer);
return 0;
}