How Long Does It Take

1.题目

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

2.译文

给定一个项目所有活动的关系,你需要找出项目的最早完成时间。

输入说明:
每个输入文件包含一个测试用例。每个测试用例以一行开始,包含两个正整数N(≤100),即活动检查点的数量(因此假设检查点从0到N-1编号),和M,即活动的数量。然后跟随M行,每行描述一个活动。对于第i个活动,给出三个非负数字:S[i],E[i]和L[i],其中S[i]是起始检查点的索引,E[i]是结束检查点的索引,L[i]是活动的持续时间。一行中的数字用空格分隔。

输出说明:
对于每个测试用例,如果调度是可能的,则打印出项目的最早完成时间;否则,简单输出"Impossible"。

3.分析

        这道题涉及到AOE网和关键路径(感兴趣的可以了解一下),但考察的点很单一,只需要找到最长的路径(最早完成时间)就可以了,通过深度搜索可以找到最长的路径,但前提是图中不能有,这就涉及到拓扑排序了,建议先了解什么是拓扑排序。

4.代码

#include<iostream>
#include<vector>
using namespace std;

//结构体邻接表存储图
struct edge {
    int from, to, w;
    edge(int a, int b, int c) { from = a, to = b, w = c; };
};
vector<edge>e[110];
int N, M, S, E, L, re, uns;
int rd[110], dir[110][110000], vis[110];
bool f = false;

//拓扑排序(命名有点随意)
//开始没用栈,出现段错误还是超时来着
void dfs()
{
    int i, j, k, count = 0;
    int ma[110], top = -1;
    for (int i = 0; i < N; i++){
        if (!rd[i]) vis[i] = 1, ma[++top] = i;
    }
    while (top != -1){
        j = ma[top--];
        count++;
        for (int i = 0; i < N; i++) {
            if (!vis[i] && dir[j][i]) {
                rd[i]--;
            }
        }
        for (int i = 0; i < N; i++) {
            if (!rd[i] && !vis[i]) {
                vis[i] = 1, ma[++top] = i;
            }
        }
    }
    if (count < N) f = false;     
    else f = true;
}

//深度搜索早最长时间
void dfs1(int u, int time)
{
    if (time > re)
        re = time;
    for (int i = 0; i < e[u].size(); i++){
        int v = e[u][i].to;
        time += e[u][i].w;
        dfs1(v, time);
        time -= e[u][i].w;
    }
}
int main()
{
    cin >> N >> M;
    for (int i = 0; i < M; i++) {
        cin >> S >> E >> L;
        e[S].push_back(edge(S, E, L));
        rd[E]++;
        dir[S][E] = 1;
    }
    for (int i = 0; i < N; i++) {
        if (!rd[i]){      //从入度为0的地方开始拓扑排序
            dfs();
        }
    }
    if (f) {
        for (int i = 0; i < N; i++) {
            if (!rd[i])          //入度为0的地方深度搜索
                dfs1(i, 0);
        }
        cout << re << endl;
    }
    else { cout << "Impossible" << endl; }
    return 0;
}

  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值