首页 > 代码库 > BZOJ 1589 采集糖果

BZOJ 1589 采集糖果

23333怎么调了一晚上。。。。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define maxv 100500#define maxe 100500using namespace std;struct edge{    int v,nxt;}e[maxe];int n,xx[maxv],g[maxv],nume=0,dfn[maxv],low[maxv],times=0,stack[maxv],top=0,dp[maxv],ret=0,hash[maxv];bool vis[maxv];void addedge(int u,int v){    e[++nume].v=v;    e[nume].nxt=g[u];    g[u]=nume;}void tarjan(int x){    vis[x]=true;dfn[x]=low[x]=++times;stack[++top]=x;    for (int i=g[x];i;i=e[i].nxt)    {        int v=e[i].v;        if (!vis[v])        {            tarjan(v);            low[x]=min(low[x],low[v]);        }        else low[x]=min(low[x],dfn[v]);    }    if (dfn[x]==low[x])    {        int p=top,cnt=0;ret++;        while (dfn[stack[p]]!=low[stack[p]])        {            cnt++;            p--;        }        cnt++;        while (dfn[stack[top]]!=low[stack[top]])        {            hash[stack[top]]=ret;            if (cnt!=1) dp[stack[top]]=cnt;            top--;        }            hash[stack[top]]=ret;        if (cnt!=1) dp[stack[top]]=cnt;        top--;    }}int find(int x){    if (dp[x]) return dp[x];    else if (xx[x]==x) {dp[x]=1;return 1;}    else return dp[x]=find(xx[x])+1;}int main(){    scanf("%d",&n);    for (int i=1;i<=n;i++)    {        scanf("%d",&xx[i]);        if (i!=xx[i])            addedge(i,xx[i]);    }    for (int i=1;i<=n;i++)    {        if (!vis[i])            tarjan(i);    }    for (int i=1;i<=n;i++)    {        if (i==xx[i])        {            dp[i]=1;            printf("1\n");        }        else printf("%d\n",find(i));    }    return 0;}

 

BZOJ 1589 采集糖果