1. 程式人生 > >[水題日常]Luogu1113 雜務

[水題日常]Luogu1113 雜務

水題 同時 code alt 天才 etc getchar() gif edge

這幾天又在頹.

我的blog難度目前還比較低,主要面向像我這樣子的新手(當然內容也會盡量講得具體清楚一些)x

如果有錯誤還請指出~


寫完隨筆之後才去翻了一下這題題解之後才註意到這題是有序的

QAQ完全不用像我這麽麻煩啊x


題目鏈接<<

題目大意:

  • 有n個雜務,完成每個雜務都需要一個時間,並且有的雜務需要在準備工作(就是其他的一些雜務)完成之後才能進行,求完成所有雜務的時間.
  • 互相沒有關系的雜務可以同時進行.
  • n<=1e5,每個雜務的準備工作不超過100個.


噫這應該算是經典題?(然而我今天才做x

一開始沒看到準備工作不超過一百個…(emm空間開不起啊咋辦?

然後又去看了一眼題面x日常石樂誌

  • 好的我們把每個雜務看成一個有權值的點.
  • 雜務需要準備工作那就向準備工作連一條有向邊.
  • 然後應該是求dag最長路?
  • 怎麽求最長路啊?
  • 我也不會求啊.
  • 直接考慮求到每個點的最長路.
  • 讀入的時候直接判一個雜務有沒有準備工作,沒有的話直接打上標記,到這個點的最長路就是這個點的權值.
  • 遍歷每個點沒有標記的話就記憶化dfs(跟dp差不多?
  • 這麽做應該可以(反正我過了=w=

貼代碼x

技術分享
#include<cstdio>
const int N=10005;
const int M=1000005;
struct edge{int to,next;}edges[M];
int head[N],cnt; int n,len,ans; int dp[N],w[N]; bool mark[N]; inline int read() { int s=0;char c;while((c=getchar())<0||c>9); do{s=s*10+c-0;}while((c=getchar())>=0&&c<=9);return s; } inline int max(int x,int y){return x>y?x:y;} inline void addEdge(int u,int v) { edges[
++cnt]=(edge){v,head[u]}; head[u]=cnt; } inline int dfs(int x) { if(mark[x])return dp[x]; int temp=0; for(int i=head[x];i;i=edges[i].next) { temp=max(temp,dfs(edges[i].to)); }mark[x]=1; return (dp[x]=temp+dp[x]); } int main() { n=read(); for(int i=1;i<=n;i++) { int key,val,temp,tot=0; key=read();val=read();dp[key]=val; while(temp=read()) { addEdge(key,temp); tot++; } if(tot==0)mark[key]=1; } for(int i=1;i<=n;i++)if(!mark[i])dfs(i); for(int i=1;i<=n;i++)ans=max(ans,dp[i]); printf("%d",ans); return 0; }
View Magical Code~

[水題日常]Luogu1113 雜務