P1113 雜務

此題困擾本宮甚久。(還不是太菜。)ios

咳咳,再說一下題意啊。。。git

有n個任務,要完成每一個任務都須要一個相應的時間,spa

而有的任務在完成以前必需要完成它對應的準備任務。blog

問完成全部的任務最少須要多少時間?get

 

搜到一份代碼emm,長這樣,string

雖然短小精悍,,但仍是沒看懂。it

 

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

int n,i,t,x,ans;
int a[10002];

int main()
{
	scanf("%d",&n);
	while(n--)
	{
		scanf("%d%d",&i,&t);
		while(scanf("%d",&x)&&x!=0)
			a[i]=max(a[i],a[x]);
		a[i]+=t;
		ans=max(ans,a[i]);
	}
	printf("%d",ans);
	return 0;
}

 

 

 

而後,爲何呢?io

咱們考慮,每一個任務要想開始的話,就必需要完成他全部的準備任務,class

那麼這個任務開始的時間就是他全部的準備任務中最晚結束的時間;stream

 

而後這個時間再加上作這個任務自己須要的時間,就是這個任務結束的時間了。

而後任務結束最晚的就是咱們要的答案了。

 

這樣看來思路好像很清晰,,,,代碼也很明白。。。

那我當時是怎麼不明白的。。。暈。

 

聽說skr很明顯的拓撲題,每一個點只有入度爲0的時候才能夠入隊。

上個圖吧,源自whymhe。。

 

解釋一下:

 

這個點(任務)被訪問,必需要在他前面的點(他的全部準備任務)全被訪問以後,

而後要在它前面的點的結束時間中取個最大值,就是這個任務的開始時間……

(同上同上)

1的結束時間:5

2的結束時間:1+5=6

4的結束時間:5+6=11

3的結束時間:6+3=8

5的結束時間:11(最大的)+1=12

6的結束時間:11(max)+8=19

7結束的時間:19(3,5,6中的max)+4=23

 

因此拓撲代碼:

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;

typedef long long LL;

inline int read()
{
	char c=getchar();
	int num=0;
	for(; !isdigit(c); c=getchar());
	for(; isdigit(c); c=getchar())
		num=num*10+c-'0';
	return num;
}

const int N=1e4+5;
const int INF=1<<30;

int n;
int rudu[N];
int f[N],g[N];
int ans;

int head[N],num_edge;
struct Edge
{
	int v,nxt;
} edge[N*1005];

inline void add_edge(int u,int v)
{
	edge[++num_edge].v=v;
	edge[num_edge].nxt=head[u];
	head[u]=num_edge;
}

queue<int> que;
void topsort()
{
	for(int i=1; i<=n; ++i)
		if(rudu[i]==0)
			que.push(i);
	int now;
	while(!que.empty())
	{
		now=que.front(),que.pop();
		f[now]+=g[now];
		if(head[now]==0)
			ans=max(ans,f[now]);
		for(int i=head[now],v; i; i=edge[i].nxt)
		{
			v=edge[i].v;
			--rudu[v];
			if(rudu[v]==0)
				que.push(v);
			g[v]=max(g[v],f[now]);
		}
	}
}

int main()
{
	n=read();
	for(int i=1,a,b; i<=n; ++i)
	{
		a=read(),f[a]=read();
		while(scanf("%d",&b)&&b)
		{
			add_edge(b,a);
			++rudu[a];
		}
	}
	topsort();
	cout<<ans;
	return 0;
}

若是你不開心,那我就把右邊這個帥傻子分享給你吧,   

你看,他這麼好看,那麼深情的望着你,你還傷心嗎?   

真的!這照片盯上他五秒鐘就想笑了。   

一切都會過去的。 

相關文章
相關標籤/搜索