洛谷P2661 信息传递

传送门

题目大意:每个人每一轮可以把消息传给另一个人,问几轮后某个人可以从人

听到自己的消息。

题解:tarjian缩点,求缩点后缩的点包含的最少的点个数。

代码:

正解

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 200009
using namespace std; int top,n,sumedge,sumclr,tim,ans;
int head[maxn],Stack[maxn],instack[maxn],low[maxn],dfn[maxn],cnt[maxn];
struct Edge{
int x,y,nxt;
Edge(int x=,int y=,int nxt=):
x(x),y(y),nxt(nxt){}
}edge[maxn]; void add(int x,int y){
edge[++sumedge]=Edge(x,y,head[x]);
head[x]=sumedge;
} void Tarjian(int x){
Stack[++top]=x;instack[x]=true;
low[x]=dfn[x]=++tim;
for(int i=head[x];i;i=edge[i].nxt){
int v=edge[i].y;
if(instack[v])low[x]=min(low[x],dfn[v]);
else if(!dfn[v]){
Tarjian(v);
low[x]=min(low[x],low[v]);
}
}
if(low[x]==dfn[x]){
++sumclr;
while(Stack[top+]!=x){
cnt[sumclr]++;
instack[Stack[top]]=false;
top--;
}
}
} int main(){
scanf("%d",&n);ans=n+;
for(int i=;i<=n;i++){
int x;
scanf("%d",&x);
add(i,x);
}
for(int i=;i<=n;i++)if(!dfn[i])Tarjian(i);
for(int i=;i<=sumclr;i++)if(cnt[i]!=)ans=min(ans,cnt[i]);
printf("%d\n",ans==n+?:ans);
return ;
}

AC

暴力

#include<iostream>
#include<algorithm>
#include<cstdio>
#define maxn 200001
using namespace std;
int n,ans,tim,m;
struct Node{
int fa,tag,v,vis;
}g[maxn];
void dfs(int x,int fa){
g[x].tag=++tim;g[x].fa=fa;
if(!g[g[x].v].fa)dfs(g[x].v,fa);
else if(g[g[x].v].fa==fa)
ans=min(ans,tim-g[g[x].v].tag+);
}
int main(){
scanf("%d",&n);ans=n+;
for(int i=;i<=n;i++)scanf("%d",&g[i].v);
for(int i=;i<=n;i++)
if(!g[i].fa)dfs(i,i);
printf("%d\n",ans);
return ;
}

AC

上一篇:Charles的HTTPS抓包方法及原理分析


下一篇:python中线程和进程的简单了解