题目描述

有 nn 个同学(编号为 11 到 nn )正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象,其中,编号为 ii 的同学的信息传递对象是编号为 T_iTi​ 的同学。

游戏开始时,每人都只知道自己的生日。之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息, 但是每人只会把信息告诉一个人,即自己的信息传递对象)。当有人从别人口中得知自 己的生日时,游戏结束。请问该游戏一共可以进行几轮?

输入输出格式

输入格式:

共22行。

第11行包含1个正整数 nn ,表示 nn 个人。

第22行包含 nn 个用空格隔开的正整数 T_1,T_2,\cdots\cdots,T_nT1​,T2​,⋯⋯,Tn​ ,其中第 ii 个整数 T_iTi​ 表示编号为 ii 的同学的信息传递对象是编号为 T_iTi​ 的同学, T_i \leq nTi​≤n 且 T_i \neq iTi​≠i 。

输出格式:

11个整数,表示游戏一共可以进行多少轮。

输入输出样例

输入样例#1: 复制

5
2 4 2 3 1
输出样例#1: 复制

3

说明

样例1解释

游戏的流程如图所示。当进行完第33 轮游戏后, 44号玩家会听到 22 号玩家告诉他自己的生日,所以答案为 33。当然,第 33 轮游戏后,22号玩家、 33 号玩家都能从自己的消息来源得知自己的生日,同样符合游戏结束的条件。

对于 30\%30%的数据, n ≤ 200n≤200;

对于 60\%60%的数据, n ≤ 2500n≤2500;

对于100\%100%的数据, n ≤ 200000n≤200000。

拓扑排序可以求是否有环   但是我不会求最小环

dfs 200000肯定会超时

可以采用拓扑排序优化 +dfs

300ms蒟蒻代码:

#include<bits/stdc++.h>
using namespace std;
//input b y bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N) for(int i=0;i<(N);i++)
#define CLR(A,v) memset(A,v,sizeof A)
#define inf 0x3f3f3f3f
//////////////////////////////////
#define N 200000+9
int in[N];
vector<int>edge[N];
int vis[N];
int minn;
void dfs(int x,int cnt,int flag)
{
vis[x]=;
int k=edge[x][];
vis[k]=;
if(k==flag)
{
minn=min(minn,cnt);
return ;
}
dfs(k,cnt+,flag);
} int main()
{
int n;
RI(n);
rep(i,,n)
{
int a,b;
RI(a);
in[a]++;
edge[i].push_back(a);
}
queue<int>q;
rep(i,,n)
if(!in[i])q.push(i);//后来还要取出来 所以这里cnt不用变
int cnt=;//计算入读为0的点
while(!q.empty())
{
int u=q.front();q.pop();
vis[u]=;//去掉不成环的点
cnt++;
if(edge[u].size())
rep(i,,edge[u].size()-)
{
int v=edge[u][i];
in[v]--;
if(in[v]==)q.push(v);
}
}
minn=inf; rep(i,,n)
if(!vis[i])
dfs(i,,i); cout<<minn; return ;
}

70ms

不要开队列!!!太慢了   只是借用拓扑排序的思想就够了

#include<bits/stdc++.h>
using namespace std;
//input b y bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N) for(int i=0;i<(N);i++)
#define CLR(A,v) memset(A,v,sizeof A)
#define inf 0x3f3f3f3f
//////////////////////////////////
#define N 200000+9
int in[N];
int edge[N];
int vis[N];
int minn;
void dfs(int x,int cnt,int flag)
{
vis[x]=;
int k=edge[x];
if(k==flag)
{
minn=min(minn,cnt);
return ;
}
dfs(k,cnt+,flag);
}
void del(int x)
{
vis[x]=;
if( --in[edge[x]]== )
del(edge[x]);
}
int main()
{
int n;
RI(n);
rep(i,,n)
{
int a,b;
RI(a);
in[a]++;
edge[i]=a;
}
rep(i,,n)
if(!in[i]&&!vis[i])
del(i); minn=inf;
rep(i,,n)
if(!vis[i])
dfs(i,,i); cout<<minn;
return ;
}

并查集 70ms

和今天写的带权并查集

一个原理

#include<bits/stdc++.h>
using namespace std;
//input b y bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N) for(int i=0;i<(N);i++)
#define CLR(A,v) memset(A,v,sizeof A)
#define inf 0x3f3f3f3f
//////////////////////////////////
#define N 200000+9
int f[N];
int dis[N];//维护距离头的距离
int minn;
int find1(int x)
{
if(x==f[x])return x;
int k=find1(f[x]);
dis[x]+=dis[f[x]];//这个只是回溯 传递 并不是改权值
return f[x]=k;
}
void union1(int a,int b)
{
int x=find1(a);
int y=find1(b);
if(x==y)
minn=min(minn,dis[a]+dis[b]+);
else
{
f[x]=y;
dis[a]=dis[b]+;//这里为改权值
}
}
int main()
{
int n;
RI(n);
rep(i,,n)
f[i]=i,dis[i]=;
minn=inf;
rep(i,,n)
{
int a;
RI(a);
union1(i,a);
}
cout<<minn;
}

P2661 信息传递 二分图的最小环的更多相关文章

  1. P2661 信息传递

    P2661 信息传递dfs求最小环,要加时间戳,记录这个点是哪一次被dfs到的.] #include<iostream> #include<cstdio> #include&l ...

  2. 洛谷P2661 信息传递(最小环,并查集)

    洛谷P2661 信息传递 最小环求解采用并查集求最小环. 只适用于本题的情况.对于新加可以使得两个子树合并的边,总有其中一点为其中一棵子树的根. 复杂度 \(O(n)\) . #include< ...

  3. 2015 提高组 信息传递--tarjan找最小环

    P2661 信息传递 题目描述 有 n 个同学(编号为 1 到 n )正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为 i 的同学的信息传递对象是编号为 Ti​ 的同学. ...

  4. 洛谷 P2661 信息传递 题解

    P2661 信息传递 题目描述 有 \(n\) 个同学(编号为 \(1\) 到 \(n\) )正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为 \(i\) 的同学的信息传 ...

  5. P2661 信息传递 DFS

    题目链接:洛谷 P2661 信息传递 一个人要想知道自己的生日,就意味着信息的传递是成环的,因为每轮信息只能传递一个人,传递的轮数就等于环的大小 环的大小就等于环中的两个点到第三个点的距离之和加一,我 ...

  6. 洛谷P2661 信息传递==coedevs4511 信息传递 NOIP2015 day1 T2

    P2661 信息传递 题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知 ...

  7. luogu P2661 信息传递 x

    P2661 信息传递 题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知 ...

  8. 洛谷 P2661 信息传递(并查集 & 最小环)

    嗯... 题目链接:https://www.luogu.org/problemnew/show/P2661 这道题和一些比较水的并查集不太一样,这道题的思路就是用并查集来求最小环... 首先,如果我们 ...

  9. P2661 信息传递[最小环+边带权并查集]

    题目来源:洛谷 题目描述 有 n 个同学(编号为 1 到 n )正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为 i 的同学的信息传递对象是编号为 Ti​ 的同学. 游戏 ...

随机推荐

  1. Laravel 5.2数据库--迁移migration

    Laravel中的migrations文件存放的是数据库表文件等结构,可以说是一个跟git差不多的,可以说像是数据库的版本控制器,所以可以叫做迁移.因为它可以很快速的很容易地构建应用的数据库表结构. ...

  2. js 数组不重复添加元素

    1 前言 由于使用JS的push会导致元素重复,而ES5之前没有set(集合)方法,重复元素还要做去重处理,比较麻烦些,所以直接写一个新push来处理 2 代码 Array.prototype.pus ...

  3. axis1 创建service服务端 , axis1 客户端

    axis1 服务端配置 1.首先建立一个项目 axisTest 不需多说 2.在lib下放入需要的jar包  点击下载 :axis所需的jar包下载 3.然后需要在web.xml里面加入: <s ...

  4. Python中join()函数方法

    函数:string.join() Python中有join()和os.path.join()两个函数,具体作用如下:    join():    连接字符串数组.将字符串.元组.列表中的元素以指定的字 ...

  5. 断路器Feign

    Feign是自带断路器,需要在配置文件中开启断路器 改造消费者项目(FeignDemo) 1.在application.yml配置文件中开启断路器 eureka: client: service-ur ...

  6. Laravel5.7 跨域解决

    先检查app/Http/Middleware/ 下是否有EnableCrossRequestMiddleware.php 这个文件,没有此文件使用此命令创建 php artisan make:midd ...

  7. PDF裁剪页面,PDF怎么裁剪页面的方法

    PDF文件要怎么裁剪页面呢,是不是有很多的小伙们想知道呢,当打开一个PDF文件的时候如果一个页面中有很多的空白页面就会影响文件的美观与使用,今天小编就为大家分享一下小编的裁剪页面的方法. 操作软件:迅 ...

  8. Django注册页面配置设计

    一.上次回顾 Django数据的增查改删 models 中有userInfo 三个字段 user password phonenumber,models.userInfo.objects.all(). ...

  9. uva11426 欧拉函数应用,kuangbin的筛法模板

    /* 给定n,对于所有的对(i,j),i<j,求出sum{gcd(i,j)} 有递推式sum[n]=sum[n-1]+f[n] 其中f[n]=gcd(1,n)+gcd(2,n)+gcd(3,n) ...

  10. tinymce-vue富文本编辑器(翻译)

    官方Tinymce Vue组件 翻译来自:https://github.com/tinymce/tinymce-vue 官方文档:https://www.tiny.cloud/docs/general ...