1. 程式人生 > >luogu1113 雜物 (拓撲排序)

luogu1113 雜物 (拓撲排序)

line 準備工作 region read 整數 std const range copy

題目描述

John的農場在給奶牛擠奶前有很多雜務要完成,每一項雜務都需要一定的時間來完成它。比如:他們要將奶牛集合起來,將他們趕進牛棚,為奶牛清洗乳房以及一些其它工作。盡早將所有雜務完成是必要的,因為這樣才有更多時間擠出更多的牛奶。當然,有些雜務必須在另一些雜務完成的情況下才能進行。比如:只有將奶牛趕進牛棚才能開始為它清洗乳房,還有在未給奶牛清洗乳房之前不能擠奶。我們把這些工作稱為完成本項工作的準備工作。至少有一項雜務不要求有準備工作,這個可以最早著手完成的工作,標記為雜務1。John有需要完成的n個雜務的清單,並且這份清單是有一定順序的,雜務k(k>1)的準備工作只可能在雜務1..k-1中。

寫一個程序從1到n讀入每個雜務的工作說明。計算出所有雜務都被完成的最短時間。當然互相沒有關系的雜務可以同時工作,並且,你可以假定John的農場有足夠多的工人來同時完成任意多項任務。

輸入輸出格式

輸入格式:

第1行:一個整數n,必須完成的雜務的數目(3<=n<=10,000);

第2 ~ n+1行: 共有n行,每行有一些用1個空格隔開的整數,分別表示:

  • 工作序號(1..n,在輸入文件中是有序的);

  • 完成工作所需要的時間len(1<=len<=100);

  • 一些必須完成的準備工作,總數不超過100個,由一個數字0結束。有些雜務沒有需要準備的工作只描述一個單獨的0,整個輸入文件中不會出現多余的空格。

輸出格式:

一個整數,表示完成所有雜務所需的最短時間。

輸入輸出樣例

輸入樣例#1: 復制
7
1 5 0
2 2 1 0
3 3 2 0
4 6 1 0
5 1 2 4 0
6 8 2 4 0
7 4 3 5 6 0
輸出樣例#1: 復制
23

秤砣找的都是些啥題啊QAQ 這題怎麽覺得用樹形DP也能水過的樣子 _(:зゝ∠)_
 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 typedef long long LL;
 4 const int MAX=10004;
 5 int n,m,ans,in[MAX],out[MAX],w[MAX],f[MAX];
6 int tot,head[MAX<<4],adj[MAX<<4],next[MAX<<4]; 7 inline int read(){ 8 int an=0,x=1;char c=getchar(); 9 while (c<0 || c>9) {if (c==-) x=-1;c=getchar();} 10 while (c>=0 && c<=9) {an=(an<<3)+(an<<1)+c-0;c=getchar();} 11 return an*x; 12 } 13 void addedge(int u,int v){ 14 tot++,in[v]++;adj[tot]=v,next[tot]=head[u],head[u]=tot; 15 } 16 void topsort(){ 17 int i,j; 18 queue <int> q; 19 for (i=1;i<=n;i++) if (!in[i]) f[i]=w[i],q.push(i); 20 while (!q.empty()){ 21 int u=q.front();q.pop(); 22 for (i=head[u];i;i=next[i]){ 23 f[adj[i]]=max(f[adj[i]],f[u]+w[adj[i]]); 24 in[adj[i]]--; 25 if (!in[adj[i]]) q.push(adj[i]); 26 } 27 } 28 } 29 int main(){ 30 freopen ("thing.in","r",stdin);freopen ("thing.out","w",stdout); 31 int i,j,zt,ans=0; 32 n=read(); 33 for (i=1;i<=n;i++){ 34 read();w[i]=read(); 35 while (zt=read()) addedge(zt,i); 36 } 37 topsort(); 38 for (i=1;i<=n;i++) ans=max(ans,f[i]); 39 printf("%d",ans); 40 return 0; 41 }



luogu1113 雜物 (拓撲排序)