NOIP2015 提高组 day1 信息传递

来源:互联网 发布:网络分线器怎么用 编辑:程序博客网 时间:2024/05/16 15:11

这里写图片描述

分析

用tarjan·强连通分量找一个最小的环

代码

const  maxn=400100;type  arr=record    x,y:longint;    next:longint;end;var  status:array[0..maxn] of boolean;  dfn,low:array[0..maxn] of longint;  sign:array[1..maxn] of longint;  edge:array[0..maxn] of arr;  ls:array[0..maxn] of longint;  zhan:array[0..maxn] of longint;  top:longint;  number:longint;  n,m,nm:longint;  shu,shu1:longint;procedure add(x,y:longint);begin  m:=m+1;  edge[m].x:=x;  edge[m].y:=y;  edge[m].next:=ls[x];  ls[x]:=m;end;procedure init;var  i,j,k:longint;begin  m:=0;  nm:=0;  fillchar(ls,sizeof(ls),0);  readln(n);  for i:=1 to n do    begin      read(j);      add(i,j);    end;end;function min(x,y:longint):longint;begin  if x>y then exit(y)         else exit(x);end;procedure dfs(x:longint);var  i,y:longint;begin  inc(number);  inc(top);  zhan[top]:=x;  dfn[x]:=number;  low[x]:=number;  i:=ls[x];  while i<>0 do    begin      y:=edge[i].y;      if dfn[y]=0        then          begin            dfs(y);            low[x]:=min(low[y],low[x]);          end        else          if not status[y]            then low[x]:=min(dfn[y],low[x]);      i:=edge[i].next;    end;  if dfn[x]=low[x]    then      begin        nm:=nm+1;        repeat          sign[nm]:=sign[nm]+1;          status[zhan[top]]:=true;          top:=top-1;        until zhan[top+1]=x;      end;end;procedure main;var  i:longint;  ans:longint;begin  number:=0;  for i:=1 to n do    if dfn[i]=0 then dfs(i);  ans:=maxlongint;  for i:=1 to nm do    if (sign[i]<ans) and (sign[i]<>1)      then ans:=sign[i];  write(ans);end;begin  assign(input,'message.in');  assign(output,'message.out');  reset(input);  rewrite(output);  init;  main;  close(input);  close(output);end.
0 0
原创粉丝点击