传送门

题目

每年万圣节,威斯康星的奶牛们都要打扮一番,出门在农场的N个牛棚里转 悠,来采集糖果.她们每走到一个未曾经过的牛棚,就会采集这个棚里的1颗糖果。农场不大,所以约翰要想尽法子让奶牛们得到快乐.他给每一个牛棚设置了一个“后继牛 棚”.牛棚i的后继牛棚是next_i 他告诉奶牛们,她们到了一个牛棚之后,只要再往后继牛棚走去, 就可以搜集到很多糖果.事实上这是一种有点欺骗意味的手段,来节约他的糖果.第i只奶牛从牛棚i开始她的旅程.请你计算,每一只奶牛可以采集到多少糖果.

分析

首先我们先进行Tarjan缩点,将每点权值赋为环中点数,意为走入这个环可获得的糖果数。因为只有一条出边,所以之后我们便进行dfs,从每一个点出发所获糖果数即为它自身权值+由它到达的点出发所能获得的糖果数。

代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
int vis[110000],size[110000],nxt[110000],ist[110000],dfn[110000],low[110000];
int sum,cnt,belong[110000],nxt2[110000],all[110000];
stack<int>a;
inline void read(int &x){
      int f=1;x=0;
      char s=getchar();
      while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
      while(s>='0'&&s<='9'){x=x*10+(s-'0');s=getchar();}
      x*=f;
}
inline void tarjan(int x){
      dfn[x]=low[x]=++cnt;
      a.push(x);
      ist[x]=1;
      if(!dfn[nxt[x]]){
          tarjan(nxt[x]);
          low[x]=min(low[x],low[nxt[x]]);
      }else if(ist[nxt[x]]){
          low[x]=min(low[x],dfn[nxt[x]]);
      }
      if(dfn[x]==low[x]){
          sum++;
          while(1){
              int u=a.top();
              a.pop();
              ist[u]=0;
              belong[u]=sum;
              all[sum]++;
              if(u==x)break;
          }
      }
}
inline void go(int x){
      if(size[x])return;
      size[x]=all[x];
      vis[x]=1;
      if(!nxt2[x])return;
      go(nxt2[x]);
      size[x]+=size[nxt2[x]];
}
int main(){
      int n,m,i,j,k;
      read(n);
      for(i=1;i<=n;i++)read(nxt[i]);
      for(i=1;i<=n;i++)
         if(!dfn[i])tarjan(i);
      for(i=1;i<=n;i++)
         if(belong[i]!=belong[nxt[i]])nxt2[belong[i]]=belong[nxt[i]];
      for(i=1;i<=sum;i++)
         if(!vis[i])
           go(i);
      for(i=1;i<=n;i++)printf("%d\n",size[belong[i]]);
      return 0;
}

最新文章

  1. Spark Shuffle数据处理过程与部分调优(源码阅读七)
  2. Python 5 —— OOP
  3. GAMIT 10.50在Ubuntu 12.04系统下的安装
  4. arcengine 常用方法
  5. C++文本的读取和写入
  6. FAQ_1_陌生的VERSION.SDK_INT
  7. Insert select 带选择复制一张表到另一张表
  8. poj 1731 Orders
  9. 程序员MM的自白:磨人小妖精之安卓碎片化
  10. 移动Oracle的用户表空间文件方法
  11. struts2拦截器拦截成功后每次请求都出现拦截时的错误信息
  12. 细说Debug和Release区别
  13. 【转】基于DM8168的视频智能分析系统的设计方案
  14. OpenStack中给wsgi程序写单元測试的方法
  15. jquery file upload 后台收到的文件名中文乱码, filename中文乱码
  16. Android手机定位技术的发展
  17. java Mybatis框架动态SQL
  18. C++11 带来的新特性 (1)
  19. python之列表及其方法---整理集
  20. 涂色(CQOI2007)

热门文章

  1. 【四】MongoDB索引管理
  2. Oil Deposits -----HDU1241暑假集训-搜索进阶
  3. css的伪类选择器的使用
  4. python Tkinter之Button
  5. unity3D编辑器扩展
  6. 分享知识-快乐自己:Linux下安装 erlang 及 RabbitmMQ
  7. BAT系列(一)— CNN
  8. Hibernate学习---第十三节:hibernate过滤器和拦截器的实现
  9. Quality
  10. POJ2774Long Long Message (后缀数组&amp;后缀自动机)