思路
此题算法:拓扑排序+DP
具体思路:
我们可以先把杂物的顺序抽象成一个又向无环图,然后进行拓扑排序
在拓扑排序的过程中进行DP,拿出队列顶端的u,并更新以u为先决杂物的v,使
AC代码
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const int N=1e5+5;
int in[N],out[N],dp[N],t[N];//in为入度,out为出度,t为每个做杂物所需的时间
int n,u,v,len,ans=0;//ans为最终答案
queue<int> q;//q用于拓扑排序的bfs
vector<int> G[N];//G由于存储邻接表
void bfs()
{
while(!q.empty())
{
int u=q.front();//取出队列顶端的u
q.pop();
for(int i=0;i<G[u].size();i++)//枚举u的先决杂物
{
int v=G[u][i];//取出先决杂物
dp[v]=max(dp[v],dp[u]+t[v]);//更新dp[v]
in[v]--;//由于已经枚举过此点,所以入度减1
if(!in[v]) q.push(v);//u还有先决杂物,将v入队
}
}
}
int main()
{
cin>>n;//读入数据
for(int i=1;i<=n;i++)
{
cin>>u>>t[u];//读入序号和做这项杂物所需的时间
while(cin>>v)
{
if(v==0) break;
G[u].push_back(v);//建邻接表
in[v]++;//增加入度
out[u]++;//增加出度
}
}
for(int i=1;i<=n;i++)
{
if(!in[i])
{
q.push(i);
dp[i]=t[i];//dp[i]的初始值为第i项杂物所需要的时间
}
}
bfs();//进行拓扑排序
for(int i=1;i<=n;i++) if(!out[i]) ans=max(ans,dp[i]);//如果此点出度不为0,更新ans
cout<<ans;
return 0;
}