题目描述
挑竹签——小时候的游戏
夏夜,早苗和诹访子在月光下玩起了挑竹签这一经典的游戏。
挑竹签,就是在桌上摆上一把竹签,每次从最上层挑走一根竹签。如果动了其他的竹签,就要换对手来挑。在所有的竹签都被挑走之后,谁挑走的竹签总数多,谁就胜了。
身为神明的诹访子自然会让早苗先手。为了获胜,早苗现在的问题是,在诹访子出手之前最多能挑走多少竹签呢?
为了简化问题,我们假设当且仅当挑最上层的竹签不会动到其他竹签。
水题
拓扑排序即可
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=1000000+10;
int dl[maxn],h[maxn],next[maxn],go[maxn],ru[maxn];
int i,j,k,l,t,n,m,ans,tot,now;
void add(int x,int y){
ru[y]++;
go[++tot]=y;
next[tot]=h[x];
h[x]=tot;
}
int read(){
int x=0,f=1;
char ch=getchar();
while (ch<'0'||ch>'9'){
if (ch=='-') f=-1;
ch=getchar();
}
while (ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
int main(){
freopen("mikado.in","r",stdin);freopen("mikado.out","w",stdout);
n=read();m=read();
fo(i,1,m){
j=read();k=read();
add(j,k);
}
k=1;l=0;
fo(i,1,n)
if (!ru[i]) dl[++l]=i;
while (k<=l){
now=dl[k++];
ans++;
t=h[now];
while (t){
ru[go[t]]--;
if (!ru[go[t]]) dl[++l]=go[t];
t=next[t];
}
}
printf("%d\n",ans);
//printf("%d\n",clock());
fclose(stdin);fclose(stdout);
return 0;
}