关键路径 p3 清华复试上机题

题目描述

小H为了完成一篇论文,一共要完成n个实验。其中第i个实验需要a[i]的时问去完成。小H可以同时进行若干实验,但存在一些实验,只有当它的若干前置实验完成时,才能开始进行该实验。同时我们认为小H在一个实验的前置实验都完成时,就能马上开始该实验。

为了让小H 尽快完成论文,需要知道在最优的情况下,最后一个完成的实验什么时候完成。

小H还想知道,在保证最后一个实验尽快完成的情况下(即保证上一间的答案不变),他想知道每个实验最晚可以什么时候开始。

设第i个实验最早可能的开始时问为fi,不能响最后一个实验完成时间的最晚开始时间为gi,请证明\(\prod_{i=0}^{n}(g_i-f_i+1)\)除以\(10^9+7\)所得的余数能够保证题目有解。

输入

从标淮输入读入数据。

第一行输入两个整数n,m。

第二行输入n个正整数 a,a[2],…,a[n],描述完成每个实验所需要的时间。

接下来读入 m 行,每行读入两个整数u,v,表示编号为u的实验是编号为v的实验的前置实验。

对于所有的输入数据,都满足\(1\leqslant n \leqslant 10^5\),\(1\leqslant m \leqslant 5×10^5\),\(1\leqslant a_i\leqslant 10^6\).

输出

输出到标准输出。

第一行输出一个整数,表示完成实验的时间。

第二行输出一个整数表示\(\prod_{i=0}^{n}(g_i-f_i+1)\)除以\(10^9+7\)所得的余数。

样例输入

7 5

11 20 17 10 11 17 17

5 4

6 1

7 3

2 4

2 1

样例输出

34

7840

解题思路

求关键路径的长度,记录每个实验最早开始时间和最晚开始时间。典型关键路径问题。

代码实现

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxn = 1e5 + 7;
const int INF = INT_MAX;
const int MOD = 1e9 + 7; vector<int> graph[maxn];
int inDegree[maxn];
ll earliest[maxn];
ll latest[maxn];
ll timee[maxn]; ll criticalPath(int n) {
vector<int> topology;
queue<int> q;
for (int i = 1; i <= n; ++i) {
if (inDegree[i] == 0) {
q.push(i);
}
}
ll totalTime = 0;//总耗时
while (!q.empty()) {
int u = q.front();
topology.push_back(u);
q.pop();
for (int i = 0; i < graph[u].size(); ++i) {
int v = graph[u][i];
inDegree[v]--;
earliest[v] = max(earliest[v], timee[u] + latest[u]);//取最大值的原因:只有当前结点的所有前驱结点活动全部完成,才能完成本结点
if (inDegree[v] == 0) {
q.push(v);
totalTime = max(totalTime, earliest[v] + timee[v]);//关键路径长度为最大路径长度的路径
}
}
}
for (int i = topology.size() - 1; i >= 0; --i) {//逆拓扑排序求最迟开始时间
int u = topology[i];
if (graph[u].size() == 0) {
latest[u] = totalTime - timee[u];//出度为0的点,最晚开始时间为关键路径长度减去其耗费时间
} else {
latest[u] = INF;//后面要求最小值,初始化为极大值
}
for (int j = 0; j < graph[u].size(); ++j) {
int v = graph[u][j];
latest[u] = min(latest[u], latest[v] - timee[u]);//非出度为0的点,最晚开始时间为所有其后续节点最晚开始时间减去该节点耗费时间的最小值
}
}
return totalTime;
} int main() {
int n, m;
while (cin >> n >> m) {
memset(graph, 0, sizeof graph);
memset(inDegree, 0, sizeof inDegree);
memset(earliest, 0, sizeof earliest);
memset(latest, 0, sizeof latest);
memset(timee, 0, sizeof timee);
for (int i = 1; i <= n; i++) {
cin >> timee[i];
}
while (m--) {
int from, to;
cin >> from >> to;
graph[from].push_back(to);
inDegree[to]++;
}
ll totalTime = criticalPath(n);
ll answer = 1;
for (int i = 1; i <= n; ++i) {
answer *= latest[i] - earliest[i] + 1;
answer %= MOD;
}
cout << totalTime << endl << answer << endl;
}
return 0;
}

关键路径 p3 清华复试上机题的更多相关文章

  1. Twin Prime Conjecture(浙大计算机研究生保研复试上机考试-2011年)

    Twin Prime Conjecture                                            Time Limit: 2000/1000 MS (Java/Othe ...

  2. HDU 1234 (浙大计算机研究生复试上机考试-2005年) 开门人和关门人 (水)

    开门人和关门人 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Su ...

  3. ZOJ问题(2010浙江大学研究生复试上机题目[找规律] hdoj 3788)

    ZOJ问题 pid=3788">点击打开链接 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  4. Java上机题(封装)(编写student类)

    今天帮大一的童鞋写Java上机题 题目虽然很简单,但是刚拿到题目的时候愣了一下,然后就疯狂get set QuQ 其实这是一个特别基本的封装的题目(之前实验室面试大二的时候竟然还有蛮多人不知道封装的概 ...

  5. Python语言上机题实现方法(持续更新...)

    Python语言上机题实现方法(持续更新...) 1.[字符串循环左移]给定一个字符串S,要求把S的前k个字符移动到S的尾部,如把字符串"abcdef"前面的2个字符'a'.'b' ...

  6. Java 哈希表(google 公司的上机题)

    1 哈希表(散列)-Google 上机题 1) 看一个实际需求,google 公司的一个上机题: 2) 有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,住址..),当输入该 ...

  7. 九度OJ1486 /POJ 1029/2012北京大学研究生复试上机

    wa到死!wa到死!这是一个看着简单,坑及其多的题! 坑一:POJ上是单组输入,九度上是多组输入,妈蛋要是研究生复试遇到这种大坑肯定死掉啊!而且对于codeforces比较习惯的 同学肯定会觉得巨坑无 ...

  8. 华为上机题汇总----java

        以下华为上机题目都是网上整理得到的,代码都是自己调试过的,由于网上java答案较少,欢迎大家批评指正,也希望对准备华为上机的童鞋们有一点点帮助.在练习的过程中成长,加油!~~  第1题:输入字 ...

  9. 浙江大学PAT上机题解析之1014. 福尔摩斯的约会 (20)

    1014. 福尔摩斯的约会 (20) 时间限制   50 ms 内存限制   32000 kB 代码长度限制   8000 B 判题程序     Standard     作者     CHEN, Y ...

随机推荐

  1. dev分支代码覆盖master分支代码

    将develop分支上的代码完全覆盖master分支, 1. 切换到master分支 git checkout master 2. 执行以下命令 git reset --hard origin/dev ...

  2. Python知识结构

    Python知识结构(点我) 欢迎评论提修改意见

  3. golang开发:go并发的建议

    这个是前段时间看到Go语言的贡献者与布道师 Dave Cheney对Go并发的建议或者叫使用的陷阱(不是我自己的建议),结合自己最近几年对gorotine的使用,再回头看这几条建议,真的会茅塞顿开,觉 ...

  4. linux中rsync备份文件

    linux中rsync备份文件 备份文件的方式 备份方式: cp : 本机复制 scp: 远程复制 推(本地上传到远程服务器): scp 1.txt root@ip:[路径] [root@m01 ~] ...

  5. Ubu18下cpptest安装

    1.环境安装 sudo apt install g++ sudo apt install automake sudo apt install autoconf sudo apt install lib ...

  6. css 实现球里装水

    <template> <div class="container">     <div class="wave"></ ...

  7. Codeforces Round #719 (Div. 3) C. Not Adjacent Matrix

    地址 Problem - C - Codeforces 题意 每个格子,该格子和相邻的格子的值不能相同 题解 思维题, 先从1~n输出奇数,再输出偶数 代码 #include <iostream ...

  8. QQ浏览器X5内核问题汇总 转

    常常被人问及微信中使用的X5内核的问题,其实我也不是很清楚,只知道它是基于android 4.2的webkit,版本号是webkit 534.今天正好从X5团队拿到了一份问题汇总,梳理下发出来,给各位 ...

  9. windwos 下编译 qsqlibase 驱动(firebird 和 interbase)

    编译环境:mingw-w64 使用qtcreator打开ibase.pro,ibase.pro位置例如:R:\qt-everywhere-opensource-src-4.8.5\src\plugin ...

  10. python学习-Day17

    目录 今日内容详细 生成器对象(自定义迭代器) 小总结 自定义range方法 通过生成器模拟range方法 先以两个参数的range方法为例 针对一个参数情况 针对三个参数情况 自定义的range方法 ...