天梯赛 最短工期(拓扑排序)

7-12 最短工期 (25 分)

一个项目由若干个任务组成,任务之间有先后依赖顺序。项目经理需要设置一系列里程碑,在每个里程碑节点处检查任务的完成情况,并启动后续的任务。现给定一个项目中各个任务之间的关系,请你计算出这个项目的最早完工时间。

输入格式:

首先第一行给出两个正整数:项目里程碑的数量 N(100)和任务总数 M。这里的里程碑从 0 到 N1 编号。随后 M 行,每行给出一项任务的描述,格式为“任务起始里程碑 任务结束里程碑 工作时长”,三个数字均为非负整数,以空格分隔。

输出格式:

如果整个项目的安排是合理可行的,在一行中输出最早完工时间;否则输出"Impossible"。

输入样例 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

输出样例 1:

18

输入样例 2:

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

输出样例 2:

Impossible



起始时间点到结束时间点,构成一条权值为工作时长的有向边。
然后跑拓扑排序即可。

代码:
#include<bits/stdc++.h>
#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair<int, int>
#define mst(a, b)    memset(a, b, sizeof a)
#define REP(i, x, n)    for(int i = x; i <= n; ++i)
#define pi acos(-1.0)
#define Max_N 1001
#define  inf 0x3f3f3f3f      
using namespace std;
const LL mod = 1e9+7;
struct node{
    int to,cost;
    node(){}
    node(int to = 0,int cost = 0):to(to),cost(cost){}
};
vector<node>v[104];
int deg[105],dis[105];
int n,m;
int cnt = 0;
queue<int>q;
void solve(){
    while(!q.empty()){
        int u = q.front();
        q.pop();
        cnt++;
        for(int i = 0 ; i < v[u].size() ; i++){
            int to   = v[u][i].to;
            int cost = v[u][i].cost;
            deg[to]--;
            if(!deg[to]) q.push(to);
            dis[to] = max(dis[to],dis[u] + cost);
        }
    }
}
int main()
{
    memset(deg,0,sizeof(deg));
    memset(dis,0,sizeof(dis));
    scanf("%d %d",&n,&m);
    for(int i = 0 ; i < m ; i ++){
        int x,y,c;
        scanf("%d %d %d",&x,&y,&c);
        v[x].push_back(node(y,c));
        deg[y]++;
    }
    for(int i = 0 ; i < n ; i ++){
        if(!deg[i]) q.push(i);
    }
    solve();
    int ans = 0;
    for(int i = 0 ; i < n ; i ++){
        ans = max(ans,dis[i]);
    }
    (cnt == n)?printf("%d\n",ans):puts("Impossible");

}

 

 

posted on 2019-03-05 22:34  Esquecer  阅读(975)  评论(0编辑  收藏  举报

导航