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>

#define MAXSIZE 100

struct ENode {
    int target;
    int weight;
    struct ENode *next;
};
typedef struct ENode *Edge;

typedef struct {
    Edge fisrtEdge;
} List[MAXSIZE];

struct Graph {
    int vertexCount;
    int edgeCount;
    List header;
};
typedef struct Graph *LGraph;

LGraph createGraph();
void topSort(LGraph graph);

int main() {
    LGraph graph = createGraph();
    topSort(graph);
    return 0;
}

LGraph createGraph() {
    int N, M;
    scanf("%d %d", &N, &M);

    LGraph graph = (LGraph) malloc(sizeof(struct Graph));
    graph->vertexCount = N;
    graph->edgeCount = M;
    for (int i = 0; i < N; i++)
        graph->header[i].fisrtEdge = NULL;
    
    for (int i = 0; i < M; i++) {
        int x, y, weight;
        scanf("%d %d %d", &x, &y, &weight);
        Edge newEdge = (Edge) malloc(sizeof(struct ENode));
        newEdge->target = y;
        newEdge->weight = weight;
        newEdge->next = graph->header[x].fisrtEdge;
        graph->header[x].fisrtEdge = newEdge;
    }

    return graph;
}

void topSort(LGraph graph) {
    int counter = 0;                            //判断是否有回路
    int dis[MAXSIZE] = {0};                     //记录到每个顶点的距离
    int indegree[MAXSIZE] = {0};                //记录每个顶点的入度
    int queue[MAXSIZE], front = 0, rear = 0;    //队列

    for (int i = 0; i < graph->vertexCount; i++)
        for (Edge e = graph->header[i].fisrtEdge; e; e = e->next)
            indegree[e->target]++;              //初始化入度
    
    for (int i = 0; i < graph->vertexCount; i++)
        if (indegree[i] == 0)
            queue[rear++] = i;                  //将入度为0的顶点入队
    
    while (front != rear) {                     //拓扑排序核心代码
        int vertex = queue[front++];
        counter++;
        for (Edge e = graph->header[vertex].fisrtEdge; e; e = e->next) {
            if (dis[vertex] + e->weight > dis[e->target])
                dis[e->target] = dis[vertex] + e->weight;   //更新dis数组
            if (--indegree[e->target] == 0) queue[rear++] = e->target;
        }
    }

    if (counter == graph->vertexCount) {        //判断是否有回路
        int max = 0;
        for (int i = 0; i < counter; i++)
            if (dis[i] > max) max = dis[i];
        printf("%d\n", max);
    } else {
        printf("Impossible\n");
    }
}
posted @ 2020-04-08 11:15  AndyHY  阅读(152)  评论(0编辑  收藏  举报