7-12 How Long Does It Take (25 分) C语言实现

思路

最近写的最爽的一题,代码量很短!不得不说y总nb!

这题感觉用邻接矩阵会更好些,更加简洁应该。但是为了锻炼一下个人用邻接表的能力,故特地采用了邻接表哈,两种都可以的~

思路就是拓扑排序的思路,采用了队列实现。

1. 一开始将入度为0的活动入队

2.将队首出队,同时对其进行拓展,也就说对其指向的点进行更新,具体为:更新时间(如果这项时间完成的时间增加了就要更新)+减少一个入度

3.如果被拓展的点中有减少入度之后为0的,那么就要将其入队

4.如此循环,直到队列为空,那么此时队列里面没有入度为零的点了,就可以结束了

5.输出的时候需要做两件事:

        1.查看是否有入度不为零的点(如果有,那么这个点就无法完成,输出impossible)

        2.更新时间的最大值,如果所有事件都可以完成,那么输出最大值

hhh,这次的代码应该跟之前的差距挺大,没有使用结构体,全部采用数组+全局变量实现了

题目

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

代码附上

//为了熟悉邻接表,这题用邻接表惹,试图学习y总的写法

#include <stdio.h>
#include <string.h>

const int N=10010;
int m,n;
int e[N],ne[N],h[N],w[N],idx;
int q[N],tt=-1,hh=-1;
int time[N];
int id[N];

void add(int a,int b,int c){
    id[b]++;
    e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}

int main(){
    int i,j;
    int a,b,c;
    memset(ne,-1,sizeof ne);
    memset(h,-1,sizeof h);
    scanf("%d%d",&n,&m);
    for(i=0;i<m;i++){
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c);
    }

    for(i=0;i<n;i++){
        if(!id[i])q[++tt]=i;
    }

    while(hh<tt){
        i=q[++hh];
        for(j=h[i];j!=-1;j=ne[j]){
            int k=e[j];
            id[k]--;
            if(time[i]+w[j]>time[k])time[k]=time[i]+w[j];
            if(!id[k])q[++tt]=k;
        }
    }
    int res=0,max=0;
    for(i=0;i<n;i++){
        if(id[i]){
            res++;
            break;
        }
        if(time[i]>max)max=time[i];
    }
    if(res)puts("Impossible");
    else printf("%d\n",max);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值