poj1949(拓扑,dp)

来源:互联网 发布:数据分析师考试大纲 编辑:程序博客网 时间:2024/05/31 00:39

点击打开题目链接

大意:

有n个任务,第i个任务需要时间xi来完成,并且第i个任务必须在它 “前面的” 某些任务完成之后才能开始。

给你任务信息,问你最短需要多少时间来完成任务。


这道题做完了以后感觉分类不太清晰,看了网上,有说拓扑排序,大多都是说是dp。

我先是想到拓扑排序的,感觉递推自然而然就用上了,dp[i]=max(dp[j]+t[i]) (j是i之前要完成的任务)(*)

这道题写写,代码跟拓扑也差不多了,顺带复习复习拓扑,括号内链接我觉得不错(拓扑学习链接)

引用下面一段:

Kahn算法:

摘一段维基百科上关于Kahn算法的伪码描述:

L← Empty list that will contain the sorted elements
S ← Set of all nodes with no incoming edges
while S is non-empty do
    remove a node n from S
    insert n into L
    foreach node m with an edge e from nto m do
        remove edge e from thegraph
        ifm has no other incoming edges then
            insert m into S
if graph has edges then
    return error (graph has at least onecycle)
else 
    return L (a topologically sortedorder)

 

不难看出该算法的实现十分直观,关键在于需要维护一个入度为0的顶点的集合:

每次从该集合中取出(没有特殊的取出规则,随机取出也行,使用队列/栈也行,下同)一个顶点,将该顶点放入保存结果的List中。

紧接着循环遍历由该顶点引出的所有边,从图中移除这条边,同时获取该边的另外一个顶点,如果该顶点的入度在减去本条边之后为0,那么也将这个顶点放到入度为0的集合中。然后继续从集合中取出一个顶点…………


这道题不是要求出拓扑序,按照上面的算法,队列已经保证了拓扑序了。此时u->v,如果u要出队的话,刚好可以

用上面的(*)式更新val[v](用于求v任务完成的最短时间)

最后答案显然就是max(val[num])(1<=num<=n)


代码如下:

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.util.Iterator;import java.util.LinkedList;import java.util.Queue;import java.util.StringTokenizer;import java.util.Vector;class Reader {static BufferedReader reader;static StringTokenizer tokenizer;static void init(InputStream input) {reader = new BufferedReader(new InputStreamReader(input));tokenizer = new StringTokenizer("");}static String next() throws IOException {while (!tokenizer.hasMoreTokens()) {tokenizer = new StringTokenizer(reader.readLine());}return tokenizer.nextToken();}static int nextInt() throws IOException {return Integer.parseInt(next());}}public class Main {/** * @param args */static int n, num, head, max;static int p[], t[], innum[], val[];static int pre[][];static Queue<Integer> queue;static Vector<Integer> vector[];public static void main(String[] args) throws IOException {// TODO Auto-generated method stubReader.init(System.in);n = Reader.nextInt();p = new int[n + 1];t = new int[n + 1];val = new int[n + 1];pre = new int[n + 1][];innum = new int[n + 1];vector = new Vector[n + 1];for (int i = 1; i <= n; i++)vector[i] = new Vector<Integer>();for (int i = 1; i <= n; i++) {t[i] = Reader.nextInt();p[i] = Reader.nextInt();pre[i] = new int[p[i] + 1];innum[i] = p[i];for (int j = 1; j <= p[i]; j++) {num = Reader.nextInt();pre[i][j] = num;vector[num].add(i);}}queue = new LinkedList<Integer>();for (int i = 1; i <= n; i++)if (innum[i] == 0) {queue.offer(i);val[i] = t[i];}while (!queue.isEmpty()) {head = queue.poll();Iterator<Integer> iter = vector[head].iterator();while (iter.hasNext()) {num = iter.next();if (val[num] < val[head] + t[num])val[num] = val[head] + t[num];innum[num]--;if (innum[num] == 0)queue.offer(num);}}max = 0;for (int i = 1; i <= n; i++)if (val[i] > max)max = val[i];System.out.println(max);}}


0 0
原创粉丝点击