from atcoder
Problem Statement
Time Limit: 2 sec / Memory Limit: 1024 MB
Score : 300300 points
Takahashi is a martial artist. There are NN moves that a martial artist can learn, called Move 11, 22, \ldots…, NN. For each 1 \leq i \leq N1≤i≤N, it takes T_iTi minutes of practice to learn Move ii. Additionally, at the beginning of that practice, all of the Moves A_{i,1}Ai,1, A_{i,2}Ai,2, \ldots…, A_{i,K_i}Ai,Ki must be already learned. Here, it is guaranteed that A_{i,j} < iAi,j<i for each 1 \leq j \leq K_i1≤j≤Ki.
Takahashi has not learned any move at time 00. He cannot practice for more than one move simultaneously, nor can he stop a practice he has already started. Find the minimum number of minutes needed for Takahashi to learn Move NN.
Constraints
Input
Input is given from Standard Input in the following format:
Output
Print the minimum number of minutes needed for Takahashi to learn Move N.
Sample Input 1 Copy
Copy
3 3 0 5 1 1 7 1 1Sample Output 1 Copy
Copy
10Here is one possible plan for Takahashi.
- At time 00, start practicing for Move 11 to learn Move 11 at time 33.
- Then, at time 33, start practicing for Move 33 to learn Move 33 at time 1010.
Here, Takahashi spends 3+7=103+7=10 minutes to learn Move 33, which is the fastest possible. Note that he does not need to learn Move 22 to learn Move 33.
Sample Input 2 Copy
Copy
5 1000000000 0 1000000000 0 1000000000 0 1000000000 0 1000000000 4 1 2 3 4Sample Output 2 Copy
Copy
5000000000Note that the answer may not fit into a 32-bit integer.
解题目标:获得学会动作Move N所需的最短时间;
题目大义:一个人要学动作,在学一个动作之前要学会一些当前动作要求的基础动作,只要学会基础动作中的一个,就可以学习当前动作了,本题input给出N个动作数量,以及学习每个动作的耗时与每个动作的基础动作,求最快学到动作N的时间;
题目类型:图,搜索,bfs,求深度和值之和。
注意点:基础动作可能存在重复情况,已经学过的动作不用重复学。
解题思路:
1)用一个邻接表来记录当前第i个Move所需的基础动作;
2)用t[]记录学第i个动作的耗时;
3)用vi[]来记录当前动作是否以及学过;
4)利用queue 边判断边加时间边压;
#include <bits/stdc++.h>
//#define MAXN 2e5+50
#define rep(x, a, b) for(int x=a; x<=b; x++)
#define per(x, a, b) for(int x=a; x>=b; x--)
using namespace std;
const int MAXN = 2e5+10;
vector<int> group[MAXN];
bool vi[MAXN];
int t[MAXN];
int main()
{
int n;
scanf("%d", &n);
rep(i, 1, n)
{
int len;
scanf("%d%d",&t[i] , &len);
// cout<<t[i]<< " "<<len<<endl;
rep(j,0, len-1)
{
int x;
scanf("%d", &x);
group[i].push_back(x);
}
}
vi[n] = true;
queue<int> que;
que.push(n);
long long ans = 0 ;
while(!que.empty())
{
int c = que.front();
que.pop();
ans += t[c];
rep(i, 0, (int)(group[c].size() - 1))
{
if(vi[group[c][i]]) continue;
else{
vi[group[c][i]] = 1;
que.push(group[c][i]);
}
}
}
cout<<ans;
return 0;
}