1. 程式人生 > 其它 >bfs,dfs,圖論

bfs,dfs,圖論

https://www.luogu.com.cn/problem/P1113

題意:給你n件任務,每個任務都有需要的時間,而且做該項任務當且僅當之前的一些任務完成,求最短時間。
思路:首先這些任務是分層的,有順序之分,想到拓撲排序,然後我的思路是標記出每一層的起點和終點,每一層求出最大時間並累加,在實現的過程中發現標記不好打,看了題解的思路,有一點dp的味道,就是其實每項任務在同一層中是相互獨立的,只與其前置任務的時間有關,然後ans是所有任務完成時間的最大值,
程式碼:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 10005
#define maxm 10000005
int ver[maxm],head[maxn],ne[maxm],endd[maxn],tim[maxn],in[maxn];
queue<int>st;
int tot=0;
void add(int x,int y){
	ver[++tot]=y;ne[tot]=head[x];head[x]=tot;
}
int n;
void SCAN()
{
	scanf("%d",&n);
	int i;
	for(i=1; i<=n; i++)
	{
		int a,c=1;
		scanf("%d",&a);
		scanf("%d",&tim[a]);
		scanf("%d",&c);
		while(c)
		{
			add(c,a);
			scanf("%d",&c);
		}
	}
}
int main(){
	memset(in,0,sizeof in);

SCAN();


int ans=0;
for(int i=0;i<10005;i++)if(in[i]==0)st.push(i);
while(!st.empty()){
	int now=st.front();st.pop();endd[now]+=tim[now];
	ans=max(ans,endd[now]);
	
	for(int i=head[now];i;i=ne[i]){
		int y=ver[i];
		in[y]--;
		endd[y]=max(endd[y],endd[now]);
		if(in[y]==0)st.push(y);
	}
	
}
cout<<ans<<endl;
return 0;}