• bzoj1064


    很巧妙的题

    首先有几种情况

    1. 有环 2.两点间有多条路径 3.其他

    3.显然最简单,最小是3,最大是每个弱联通块中最长链

    2.显然,两点间两条路径的差是答案的倍数

    1.出现环,那答案一定是其约数,那么最大答案就是所有环长的最大公约数,最小是最大的大于等于3的最小因数

    综合以上,我们就有了大概的思路,但是不好处理

    有一个精妙的做法,对于每条边添加一个长度为-1的反向边,一下就简单多了

      1 type node=record
      2        po,next,num:longint;
      3      end;
      4 
      5 var e:array[0..4000010] of node;
      6     p,d:array[0..200010] of longint;
      7     v:array[0..200010] of boolean;
      8     mi,i,l,r,n,m,len,ans,x,y:longint;
      9 
     10 function min(a,b:longint):longint;
     11   begin
     12     if a>b then exit(b) else exit(a);
     13   end;
     14 
     15 function max(a,b:longint):longint;
     16   begin
     17     if a>b then exit(a) else exit(b);
     18   end;
     19 
     20 function gcd(a,b:longint):longint;
     21   begin
     22     if b=0 then exit(a)
     23     else exit(gcd(b,a mod b));
     24   end;
     25 
     26 procedure add(x,y,z:longint);
     27   begin
     28     inc(len);
     29     e[len].po:=y;
     30     e[len].num:=z;
     31     e[len].next:=p[x];
     32     p[x]:=len;
     33   end;
     34 
     35 procedure dfs(x:longint);
     36   var i,y:longint;
     37   begin
     38     v[x]:=true;
     39     i:=p[x];
     40     while i<>-1 do
     41     begin
     42       y:=e[i].po;
     43       if v[y] then ans:=gcd(ans,abs(d[x]+e[i].num-d[y]))
     44       else begin
     45         d[y]:=d[x]+e[i].num;
     46         dfs(y);
     47       end;
     48       i:=e[i].next;
     49     end;
     50   end;
     51 
     52 procedure find(x:longint);
     53   var i,y:longint;
     54   begin
     55     v[x]:=true;
     56     l:=min(l,d[x]);
     57     r:=max(r,d[x]);
     58     i:=p[x];
     59     while i<>-1 do
     60     begin
     61       y:=e[i].po;
     62       if not v[y] then
     63       begin
     64         d[y]:=d[x]+e[i].num;
     65         find(y);
     66       end;
     67       i:=e[i].next;
     68     end;
     69   end;
     70 
     71 begin
     72   len:=-1;
     73   fillchar(p,sizeof(p),255);
     74   readln(n,m);
     75   for i:=1 to m do
     76   begin
     77     readln(x,y);
     78     add(x,y,1);
     79     add(y,x,-1);
     80   end;
     81   for i:=1 to n do
     82     if not v[i] then dfs(i);
     83   if ans<>0 then
     84   begin
     85     mi:=ans;
     86     for i:=3 to ans do
     87       if ans mod i=0 then
     88       begin
     89         mi:=i;
     90         break;
     91       end;
     92   end
     93   else begin
     94     fillchar(v,sizeof(v),false);
     95     for i:=1 to n do
     96       if not v[i] then
     97       begin
     98         d[i]:=0;
     99         l:=0;  r:=0;
    100         find(i);
    101         ans:=ans+r-l+1;
    102       end;
    103 
    104     mi:=3;
    105   end;
    106   if ans<3 then writeln('-1 -1') else writeln(ans,' ',mi);
    107 end.
    View Code
  • 相关阅读:
    ios每日一发--Leanclude数据云存储以及登录 注册账户
    ios每日一发--仿侧边抽屉效果
    ios-自定义alertView提示框
    ios
    UIStepper 缩放:UI的使用
    UIButton 关灯小实验
    将一个字典内的内value转换为集合:返回一个数组,此数组中包含输入字典的键值对中的数组的所有元素(为NSArray添加category)
    为集合排序的三个方法
    NSMutableDictionary
    头文件导入方式
  • 原文地址:https://www.cnblogs.com/phile/p/4590647.html
Copyright © 2020-2023  润新知