洛谷 P1113 雜務 ( dp or拓撲) 題解
題目來源:
題目描述:
題目描述
John
的農場在給奶牛擠奶前有很多雜務要完成,每一項雜務都需要一定的時間來完成它。比如:他們要將奶牛集合起來,將他們趕進牛棚,為奶牛清洗乳房以及一些其它工作。儘早將所有雜務完成是必要的,因為這樣才有更多時間擠出更多的牛奶。當然,有些雜務必須在另一些雜務完成的情況下才能進行。比如:只有將奶牛趕進牛棚才能開始為它清洗乳房,還有在未給奶牛清洗乳房之前不能擠奶。我們把這些工作稱為完成本項工作的準備工作。至少有一項雜務不要求有準備工作,這個可以最早著手完成的工作,標記為雜務11。John
有需要完成的nn個雜務的清單,並且這份清單是有一定順序的,雜務k(k>1)k(k>1)的準備工作只可能在雜務11至k-1k−1中。
寫一個程式從11到nn讀入每個雜務的工作說明。計算出所有雜務都被完成的最短時間。當然互相沒有關係的雜務可以同時工作,並且,你可以假定John
的農場有足夠多的工人來同時完成任意多項任務。
輸入輸出格式
輸入格式:
第1行:一個整數nn,必須完成的雜務的數目(3 \le n \le 10,0003≤n≤10,000);
第22至(n+1)(n+1)行: 共有nn行,每行有一些用11個空格隔開的整數,分別表示:
* 工作序號(11至nn,在輸入檔案中是有序的);
* 完成工作所需要的時間len(1 \le len \le 100)len(1≤len≤100);
* 一些必須完成的準備工作,總數不超過100100個,由一個數字00結束。有些雜務沒有需要準備的工作只描述一個單獨的00,整個輸入檔案中不會出現多餘的空格。
輸出格式:
一個整數,表示完成所有雜務所需的最短時間。
輸入輸出樣例
輸入樣例#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
解題思路:
我們知道因為讀入是有序的,所以每個節點是時間就是他的前驅完成任務的最大時間加上自己的時間,隨便更新答案就行。
我的程式碼是用拓撲排序做的,會慢一點
#include <iostream> #include <queue> #include <cstring> #include <string> #include <vector> #include <stack> using namespace std; vector<int>E[10005]; vector<int>EE[10005]; int rd[10005],sj[10005],wc[10005]; int main() { int n; cin>>n; memset(rd,0,sizeof(rd)); memset(sj,0,sizeof(sj)); memset(wc,0,sizeof(wc)); for(int i=1;i<=n;i++) { int a,b; cin>>a>>b; sj[a]=b; int c; while(cin>>c&&c) { rd[a]++; E[c].push_back(a); EE[a].push_back(c); } } queue<int>q; int maxn=0,ans=0; for(int i=1;i<=n;i++) { if(rd[i]==0){ q.push(i); wc[i]=sj[i]; } } while(!q.empty()) { int now=q.front(); q.pop(); for(int i=0;i<E[now].size();i++) { int v=E[now][i]; rd[v]--; maxn=0; wc[v]=max(wc[v],wc[now]+sj[v]); ans=max(ans,wc[v]); if(rd[v]==0) { q.push(v); } } } cout<<ans<<endl; return 0; }
。