您的位置:首页 > 其它

挑竹签

2016-03-09 19:01 435 查看

题目描述

挑竹签——小时候的游戏

夏夜,早苗和诹访子在月光下玩起了挑竹签这一经典的游戏。

挑竹签,就是在桌上摆上一把竹签,每次从最上层挑走一根竹签。如果动了其他的竹签,就要换对手来挑。在所有的竹签都被挑走之后,谁挑走的竹签总数多,谁就胜了。

身为神明的诹访子自然会让早苗先手。为了获胜,早苗现在的问题是,在诹访子出手之前最多能挑走多少竹签呢?

为了简化问题,我们假设当且仅当挑最上层的竹签不会动到其他竹签。

水题

拓扑排序即可

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: