08-图8 How Long Does It Take (25 分)

Given the relations of all the activities of a project, you are supposed to find the earliest completion time of the project.

Input Specification:

Each input file contains one test case. Each case starts with a line containing two positive integers N (≤100), the number of activity check points (hence it is assumed that the check points are numbered from 0 to N−1), and M, the number of activities. Then M lines follow, each gives the description of an activity. For the i-th activity, three non-negative numbers are given: S[i]E[i], and L[i], where S[i] is the index of the starting check point, E[i] of the ending check point, and L[i] the lasting time of the activity. The numbers in a line are separated by a space.

Output Specification:

For each test case, if the scheduling is possible, print in a line its earliest completion time; or simply output "Impossible".

Sample Input 1:

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

结尾无空行

Sample Output 1:

18

结尾无空行

Sample Input 2:

4 5
0 1 1
0 2 2
2 1 3
1 3 4
3 2 5

Sample Output 2:

Impossible

 

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MaxVertexNum 105
#define INFINITY 65535

typedef int Vertex;
typedef int WeightType;

//邻接点的定义
typedef struct AdjaVNode * PtrToAdjaVNode;
struct AdjaVNode{
    Vertex AdjaV;
    WeightType Weight;
    PtrToAdjaVNode Next;
};

//顶点表头结点的定义
typedef struct Vnode {
    PtrToAdjaVNode FirstEdge;
    //DataType Data;//如果顶点需要存储数据
}AdjaList[MaxVertexNum];

//图结点的定义
typedef struct GNode * PtrToGNode;
struct GNode {
    int Nv;
    int Ne;
    AdjaList G;//邻接表为一个结构数组
};
typedef PtrToGNode LGraph;

//边的定义
typedef struct ENode * PtrToENode;
struct ENode {
    Vertex V1,V2;
    WeightType Weight;
};
typedef PtrToENode Edge;


//队列的节点
typedef Vertex ElementType;
struct QNode{
    ElementType Element;
    struct QNode * Next;
};
//队列的空头节点,含有指向头尾的指针
struct HeaderQNode{
    struct QNode * Front;
    struct QNode * Rear;
};
typedef struct HeaderQNode * Queue;

LGraph CreateGraph(int VertexNum){
    LGraph graph=(LGraph)malloc(sizeof(struct GNode));
    Vertex V;

    graph->Nv=VertexNum;
    graph->Ne=0;
    for(V=0;V<VertexNum;V++){
        graph->G[V].FirstEdge=NULL;
    }

    return graph;
}

void InsertEdge(LGraph graph,Edge E){
    //插入边<V1,V2>
    PtrToAdjaVNode NewNode=(PtrToAdjaVNode)malloc(sizeof(struct AdjaVNode));
    NewNode->Next = graph->G[E->V1].FirstEdge;
    graph->G[E->V1].FirstEdge=NewNode;
    NewNode->AdjaV=E->V2;
    NewNode->Weight=E->Weight;
}

LGraph ReadBuildGraph(){
    //输入格式为顶点 边数\n然后每行:起点 终点 权重
    int VertexNum,i;

    scanf("%d",&VertexNum);
    LGraph graph=CreateGraph(VertexNum);
    scanf("%d",&graph->Ne);
    if(graph->Ne){
        Edge E=(Edge)malloc(sizeof(struct ENode));
        for(i=0;i<graph->Ne;i++){
            scanf("%d %d %d",&E->V1,&E->V2,&E->Weight);
            InsertEdge(graph,E);
        }
    }
    return graph;
}



//以下为队列
struct HeaderQNode * CreateQueue(void)
{
    struct HeaderQNode * p;
    p=(struct HeaderQNode *)malloc(sizeof(struct HeaderQNode));
    p->Front=NULL;p->Rear=NULL;
    return p;
}
bool IsEmpty(struct HeaderQNode * p)
{
    if(p->Rear==NULL)   return true;
    else    return false;
}
void EnQueue(struct HeaderQNode * p,ElementType V)
{
    struct QNode * temp=(struct QNode *)malloc(sizeof(struct QNode));temp->Element=V;
    if(p->Rear==NULL){
        p->Front=temp;
        temp->Next=NULL;
        p->Rear=temp;
    }else {
        p->Rear->Next=temp;
        temp->Next=NULL;
        p->Rear=temp;
    }
}
ElementType DeQueue(struct HeaderQNode * p)
{
    ElementType ret;
    if(!IsEmpty(p)){
        struct QNode * temp=p->Front;
        ret=temp->Element;
        p->Front=temp->Next;
        if(p->Front==NULL)  p->Rear=NULL;
        free(temp);
    }else   return 0;
    return ret;
}//队列定义结束



int TopSort( LGraph Graph, int Earliest[] )
{ /* 对Graph进行拓扑 */
    int Indegree[MaxVertexNum], cnt ;
    //int Max[MaxVertexNum]={0};
    Vertex V;
    PtrToAdjaVNode W;
    Queue Q = CreateQueue();

    /* 初始化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->AdjaV]++; /* 对有向边<V, W->AdjV>累计终点的入度 */

    /* 将所有入度为0的顶点入列 */
    for (V=0; V<Graph->Nv; V++)
        if ( Indegree[V]==0 )
            EnQueue(Q, V);

    /* 下面进入拓扑排序 */
    cnt = 0;
    while( !IsEmpty(Q) ){
        V = DeQueue(Q); /* 弹出一个入度为0的顶点 */
        cnt++;

        /* 对V的每个邻接点W->AdjaV */
        for ( W=Graph->G[V].FirstEdge; W; W=W->Next ){
            if(Earliest[V]+W->Weight>Earliest[W->AdjaV]){
                Earliest[W->AdjaV]=Earliest[V]+W->Weight;
                //Max[W->AdjaV]=Earliest[W->AdjaV];
            }
            if ( --Indegree[W->AdjaV] == 0 )/* 若删除V使得W->AdjV入度为0 */
                EnQueue(Q, W->AdjaV); /* 则该顶点入列 */
        }
    } /* while结束*/

    int result=0;
    if ( cnt != Graph->Nv )
        return 0; /* 说明图中有回路, 返回不成功标志 */
    else{
        //注意多个终点的情况
        for(V=0;V<Graph->Nv;V++){
            if(Earliest[V]>result)
                result=Earliest[V];
        }
    }
    return result;
}

int main()
{
    int answer;
    LGraph graph=ReadBuildGraph();
    int Earliest[MaxVertexNum]={0};
    answer=TopSort(graph,Earliest);
    if(answer)
        printf("%d",answer);
    else printf("Impossible");

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值