暫無鏈接
遊戲攻略
GISPZJZ 在玩一款火爆的遊戲,遊戲中有個技能點,編號分別爲。有些技能 點可以直接學習,還有一些技能點需要你已經學習某些技能點,才能夠學習。一開始 GISPZJZ 沒有學習任何技能點,現在 GISPZJZ 想知道,他最多能夠學習技能池裏的多少個技能。
輸入:
第一行一個正整數。
接下來 行,第 行先輸入一個整數 ,接下來輸入 個正整數 。 表示學習第 個技能,需要先學習的技能點。 表示學習 技能沒有任何前置條件。
輸出:
一行一個整數 ,表示 GISPZJZ 能學習的最大技能數。
樣例輸入:
4
0
1 1
2 1 4
2 1 3
樣例輸出:
2
樣例說明:
GISPZJZ 可以按順序學習技能 1,技能 2,然後無法獲得其他的技能點。
數據範圍:
對於 的數據,。
對於 的數據,。
對於額外 的數據,滿足對任意 。
對於額外 的數據,滿足對任意 。
對於 的數據,。
題解
技能加點相當於一個圖,每次將入度爲的點刪去,更新其他點的入度,答案,類似於拓撲排序。
不知道爲什麼考場上腦子抽了寫一個用優先隊列的算法。。。
代碼
#include<bits/stdc++.h>
using namespace std;
const int M=1e5+5;
struct sd{int id,du;};
bool operator<(sd a,sd b){return a.du>b.du;}
int ru[M],n,ans;
bool vis[M];
vector<int>mmp[M];
priority_queue<sd>dui;
void in()
{
scanf("%d",&n);
for(int i=1,j,a,b;i<=n;dui.push((sd){i,ru[i]}),++i)
for(scanf("%d",&a),ru[i]=a,j=1;j<=a;++j)
scanf("%d",&b),mmp[b].push_back(i);
}
void ac()
{
for(sd f;!dui.empty();)
{
f=dui.top();dui.pop();
if(vis[f.id])continue;
if(f.du)break;
vis[f.id]=1,++ans;
for(int i=mmp[f.id].size()-1;i>=0;--i)
dui.push((sd){mmp[f.id][i],--ru[mmp[f.id][i]]});
}
printf("%d",ans);
}
int main(){in(),ac();