#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MaxVertexNum 100 /* 最大定点数设为100 */
typedef int Vertex; /* 用顶点下标表示顶点,为整形 */
typedef int WeightType; /* 边的权值设为整形 */
typedef char DataType; /* 顶点储存的数据类型设为字符型 */
int time[MaxVertexNum]={0};
/* 队列的相关操作 */
/* 队列的顺序储存实现结构定义 */
typedef int ElementType;
typedef int Position;
typedef struct QNode *PtrToQNode;
struct QNode{
ElementType *Data; /* 储存元素的数组 */
Position Front, Rear; /* 队列的头尾指针 */
int MaxSize; /* 队列的最大容量 */
};
typedef PtrToQNode Queue;
/* 队列的创建 */
Queue CreatQueue(int MaxSize)
{
Queue Q = (Queue)malloc(sizeof(struct QNode));
Q->Data = (ElementType *)malloc(MaxSize*sizeof(ElementType));
Q->Front = Q->Rear=0;
Q->MaxSize = MaxSize;
return Q;
}
int IsFull(Queue Q)
{
if((Q->Rear+1)%Q->MaxSize==Q->Front)
return 1;
else
return 0;
}
void AddQ(Queue Q, ElementType X) /* 入队列 */
{
if(IsFull(Q)){
printf("队列满");
}
else{
Q->Rear = (Q->Rear+1)%Q->MaxSize;
Q->Data[Q->Rear] = X;
}
}
int IsEmpty(Queue Q) /* 判断队列是否为空 */
{
if(Q->Front==Q->Rear)
return 1;
else
return 0;
}
ElementType DeleteQ(Queue Q) /* 出队列 */
{
if(IsEmpty(Q)) {
printf("队列空");
}
else {
Q->Front = (Q->Front+1)%Q->MaxSize;
return Q->Data[Q->Front];
}
}
/* 边的定义 */
typedef struct ENode *PtrToENode;
struct ENode{
Vertex V1, V2; /* 有向边<V1, V2> */
WeightType Weight; /* 权重 */
};
typedef PtrToENode Edge;
/* 邻结点的定义 */
typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{
Vertex AdjV; /* 邻接点下标 */
WeightType Weight; /* 边权重 */
PtrToAdjVNode Next;
};
/* 顶点表头节点的定义 */
typedef struct Vnode{
PtrToAdjVNode FirstEdge; /* 边表头指针 */
//DataType Data;
}AdjList[MaxVertexNum]; /* AdjList 是邻接表的类型 */
/* 图节点的定义 */
typedef struct GNode *ProToGNode;
struct GNode{
int Nv; /* 顶点数 */
int Ne; /* 边数 */
AdjList G; /* 邻接表 */
};
typedef ProToGNode LGraph;
int TopOrder[MaxVertexNum];
LGraph CreateGraph(int VertexNum) /* 初始化一个有N个顶点但是没有边的图 */
{
Vertex V;
LGraph Graph;
Graph=(LGraph)malloc(sizeof(struct GNode)); /* 建立图 */
Graph->Nv=VertexNum;
Graph->Ne=0;
/* 初始化邻接表头指针 */
for( V = 0; V < Graph->Nv; V++)
Graph->G[V].FirstEdge=NULL;
return Graph;
}
void InsertEdge(LGraph Graph, Edge E) //插入边
{
PtrToAdjVNode NewNode;
/*插入边 <v1, v2>*/
/* 为V2建立新的邻接点 */
NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
NewNode->AdjV = E->V2;
NewNode->Weight = E->Weight;
/* 将V2插入V1的表头 */
NewNode->Next=Graph->G[E->V1].FirstEdge;
Graph->G[E->V1].FirstEdge=NewNode;
/* 若是无向图还要插入边 */
/*为V1建立新的邻接点 */
//省略这一步
}
LGraph BuildGraph()
{
LGraph Graph;
Edge E;
Vertex V;
int Nv, i;
scanf("%d", &Nv); /* 读入顶点数 */
Graph = CreateGraph(Nv); /* 初始化一个有Nv个顶点但是没有边的图 */
scanf("%d", &(Graph->Ne)); /* 读入边数 */
if(Graph->Ne != 0) {/* 如果有边 */
E=(Edge)malloc(sizeof(struct ENode)); /* 建立边结点 */
/* 读入边,格式为 "起点 终点 权重” */
for(i=0; i<Graph->Ne; i++){
scanf("%d %d %d",&E->V1,&E->V2,&E->Weight);
/* 注意如果weight不是整形 weight的输入格式要更改*/
InsertEdge(Graph, E);
}
}
/* 如果顶点有数据的话,读入顶点数据 */
/*
for(V = 0; V < Graph->Nv; V++)
scanf("%c",&(Graph->G[V].Data));
*/
return Graph;
}
int TopSort(LGraph Graph) /*拓扑排序*/
{
/* Indegree计算顶各个顶点的入度 */
int Indegree[MaxVertexNum], cnt;
Vertex V;
PtrToAdjVNode W;
Queue Q = CreatQueue(Graph->Nv);
/* 初始化Indegree[] */
for( V = 0; V<Graph->Nv; V++)
Indegree[V]=0;
/* 遍历图,得到Indegree[] */
for( V = 0; V<Graph->Nv; V++)
for(W = Graph->G[V].FirstEdge; W; W = W->Next)
Indegree[W->AdjV]++; //入度增加
/* 将所有入度为零的顶点入队列 */
for(V = 0;V < Graph->Nv; V++)
if(Indegree[V]==0)
AddQ(Q, V);
cnt = 0;
while(!IsEmpty(Q)){
V = DeleteQ(Q); /* 弹出一个入度为零的顶点 */
//printf("%d\n",V);
/* 求最短工期 */
for(W=Graph->G[V].FirstEdge; W!=NULL; W = W->Next)
{
if(time[W->AdjV]<time[V]+W->Weight)
time[W->AdjV]=time[V]+W->Weight;
}
TopOrder[cnt++] = V; /* 将之存为结果序列的下一个元素 */
for(W=Graph->G[V].FirstEdge; W!=NULL; W = W->Next)
{
if(--Indegree[W->AdjV]==0) //若删除V使得W-Adiv入度为零
AddQ(Q, W->AdjV); //则此顶点入队列
}
}
if(cnt != Graph->Nv)
return -1;
else
return 1;
}
int main()
{
int N;
LGraph Graph;
Graph=BuildGraph(); /* 建立一个邻接表,并读入全部数据到表中 */
/* 之后进行拓扑排序 */
N=TopSort(Graph); /* 拓扑排序 */
if(N==1)
{
int Max=time[0];
for(int i=1;i<Graph->Nv;i++)
{
if(time[i]>Max)
Max=time[i];
}
printf("%d",Max);
}
else
printf("Impossible");
return 0;
}
#include<string.h>
#include<stdlib.h>
#define MaxVertexNum 100 /* 最大定点数设为100 */
typedef int Vertex; /* 用顶点下标表示顶点,为整形 */
typedef int WeightType; /* 边的权值设为整形 */
typedef char DataType; /* 顶点储存的数据类型设为字符型 */
int time[MaxVertexNum]={0};
/* 队列的相关操作 */
/* 队列的顺序储存实现结构定义 */
typedef int ElementType;
typedef int Position;
typedef struct QNode *PtrToQNode;
struct QNode{
ElementType *Data; /* 储存元素的数组 */
Position Front, Rear; /* 队列的头尾指针 */
int MaxSize; /* 队列的最大容量 */
};
typedef PtrToQNode Queue;
/* 队列的创建 */
Queue CreatQueue(int MaxSize)
{
Queue Q = (Queue)malloc(sizeof(struct QNode));
Q->Data = (ElementType *)malloc(MaxSize*sizeof(ElementType));
Q->Front = Q->Rear=0;
Q->MaxSize = MaxSize;
return Q;
}
int IsFull(Queue Q)
{
if((Q->Rear+1)%Q->MaxSize==Q->Front)
return 1;
else
return 0;
}
void AddQ(Queue Q, ElementType X) /* 入队列 */
{
if(IsFull(Q)){
printf("队列满");
}
else{
Q->Rear = (Q->Rear+1)%Q->MaxSize;
Q->Data[Q->Rear] = X;
}
}
int IsEmpty(Queue Q) /* 判断队列是否为空 */
{
if(Q->Front==Q->Rear)
return 1;
else
return 0;
}
ElementType DeleteQ(Queue Q) /* 出队列 */
{
if(IsEmpty(Q)) {
printf("队列空");
}
else {
Q->Front = (Q->Front+1)%Q->MaxSize;
return Q->Data[Q->Front];
}
}
/* 边的定义 */
typedef struct ENode *PtrToENode;
struct ENode{
Vertex V1, V2; /* 有向边<V1, V2> */
WeightType Weight; /* 权重 */
};
typedef PtrToENode Edge;
/* 邻结点的定义 */
typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{
Vertex AdjV; /* 邻接点下标 */
WeightType Weight; /* 边权重 */
PtrToAdjVNode Next;
};
/* 顶点表头节点的定义 */
typedef struct Vnode{
PtrToAdjVNode FirstEdge; /* 边表头指针 */
//DataType Data;
}AdjList[MaxVertexNum]; /* AdjList 是邻接表的类型 */
/* 图节点的定义 */
typedef struct GNode *ProToGNode;
struct GNode{
int Nv; /* 顶点数 */
int Ne; /* 边数 */
AdjList G; /* 邻接表 */
};
typedef ProToGNode LGraph;
int TopOrder[MaxVertexNum];
LGraph CreateGraph(int VertexNum) /* 初始化一个有N个顶点但是没有边的图 */
{
Vertex V;
LGraph Graph;
Graph=(LGraph)malloc(sizeof(struct GNode)); /* 建立图 */
Graph->Nv=VertexNum;
Graph->Ne=0;
/* 初始化邻接表头指针 */
for( V = 0; V < Graph->Nv; V++)
Graph->G[V].FirstEdge=NULL;
return Graph;
}
void InsertEdge(LGraph Graph, Edge E) //插入边
{
PtrToAdjVNode NewNode;
/*插入边 <v1, v2>*/
/* 为V2建立新的邻接点 */
NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
NewNode->AdjV = E->V2;
NewNode->Weight = E->Weight;
/* 将V2插入V1的表头 */
NewNode->Next=Graph->G[E->V1].FirstEdge;
Graph->G[E->V1].FirstEdge=NewNode;
/* 若是无向图还要插入边 */
/*为V1建立新的邻接点 */
//省略这一步
}
LGraph BuildGraph()
{
LGraph Graph;
Edge E;
Vertex V;
int Nv, i;
scanf("%d", &Nv); /* 读入顶点数 */
Graph = CreateGraph(Nv); /* 初始化一个有Nv个顶点但是没有边的图 */
scanf("%d", &(Graph->Ne)); /* 读入边数 */
if(Graph->Ne != 0) {/* 如果有边 */
E=(Edge)malloc(sizeof(struct ENode)); /* 建立边结点 */
/* 读入边,格式为 "起点 终点 权重” */
for(i=0; i<Graph->Ne; i++){
scanf("%d %d %d",&E->V1,&E->V2,&E->Weight);
/* 注意如果weight不是整形 weight的输入格式要更改*/
InsertEdge(Graph, E);
}
}
/* 如果顶点有数据的话,读入顶点数据 */
/*
for(V = 0; V < Graph->Nv; V++)
scanf("%c",&(Graph->G[V].Data));
*/
return Graph;
}
int TopSort(LGraph Graph) /*拓扑排序*/
{
/* Indegree计算顶各个顶点的入度 */
int Indegree[MaxVertexNum], cnt;
Vertex V;
PtrToAdjVNode W;
Queue Q = CreatQueue(Graph->Nv);
/* 初始化Indegree[] */
for( V = 0; V<Graph->Nv; V++)
Indegree[V]=0;
/* 遍历图,得到Indegree[] */
for( V = 0; V<Graph->Nv; V++)
for(W = Graph->G[V].FirstEdge; W; W = W->Next)
Indegree[W->AdjV]++; //入度增加
/* 将所有入度为零的顶点入队列 */
for(V = 0;V < Graph->Nv; V++)
if(Indegree[V]==0)
AddQ(Q, V);
cnt = 0;
while(!IsEmpty(Q)){
V = DeleteQ(Q); /* 弹出一个入度为零的顶点 */
//printf("%d\n",V);
/* 求最短工期 */
for(W=Graph->G[V].FirstEdge; W!=NULL; W = W->Next)
{
if(time[W->AdjV]<time[V]+W->Weight)
time[W->AdjV]=time[V]+W->Weight;
}
TopOrder[cnt++] = V; /* 将之存为结果序列的下一个元素 */
for(W=Graph->G[V].FirstEdge; W!=NULL; W = W->Next)
{
if(--Indegree[W->AdjV]==0) //若删除V使得W-Adiv入度为零
AddQ(Q, W->AdjV); //则此顶点入队列
}
}
if(cnt != Graph->Nv)
return -1;
else
return 1;
}
int main()
{
int N;
LGraph Graph;
Graph=BuildGraph(); /* 建立一个邻接表,并读入全部数据到表中 */
/* 之后进行拓扑排序 */
N=TopSort(Graph); /* 拓扑排序 */
if(N==1)
{
int Max=time[0];
for(int i=1;i<Graph->Nv;i++)
{
if(time[i]>Max)
Max=time[i];
}
printf("%d",Max);
}
else
printf("Impossible");
return 0;
}