bzoj2791

每个顶点有且仅有一条出边是什么意思呢

类似一棵树,树上的边都是由儿子指向父亲的,并且这个东西带着一个环

也就是一个个有向环套有向树……

这题还是比较简单的,把环作为根然后类似lca做即可,注意细节的panding

  1 type node=record
  2        po,next:longint;
  3      end;
  4 
  5 var e:array[0..500010] of node;
  6     s,p,w,c,be,d,q:array[0..500010] of longint;
  7     v:array[0..500010] of boolean;
  8     anc:array[0..500010,0..20] of longint;
  9     t,f,r,n,m,len,i,x,y,a,b:longint;
 10 
 11 function max(a,b:longint):longint;
 12   begin
 13     if a>b then exit(a) else exit(b);
 14   end;
 15 
 16 function min(a,b:longint):longint;
 17   begin
 18     if a>b then exit(b) else exit(a);
 19   end;
 20 
 21 procedure swap(var a,b:longint);
 22   var c:longint;
 23   begin
 24     c:=a;
 25     a:=b;
 26     b:=c;
 27   end;
 28 
 29 procedure add(x,y:longint);
 30   begin
 31     inc(len);
 32     e[len].po:=y;
 33     e[len].next:=p[x];
 34     p[x]:=len;
 35   end;
 36 
 37 procedure bfs;
 38   var x,i,y:longint;
 39   begin
 40     f:=1;
 41     while f<=r do
 42     begin
 43       x:=q[f];
 44       for i:=1 to 20 do
 45       begin
 46         y:=anc[x,i-1];
 47         if y<>0 then anc[x,i]:=anc[y,i-1] else break;
 48       end;
 49       i:=p[x];
 50       while i<>0 do
 51       begin
 52         y:=e[i].po;
 53         if not v[y] then
 54         begin
 55           d[y]:=d[x]+1;
 56           anc[y,0]:=x;
 57           be[y]:=t;
 58           inc(r);
 59           q[r]:=y;
 60           v[y]:=true;
 61         end;
 62         i:=e[i].next;
 63       end;
 64       inc(f);
 65     end;
 66   end;
 67 
 68 procedure lca(x,y:longint);
 69   var i,num,a1,b1,a2,b2:longint;
 70   begin
 71     a:=0; b:=0;
 72     if d[x]>d[y] then
 73       for i:=20 downto 0 do
 74         if d[x]-1 shl i>=d[y] then
 75         begin
 76           x:=anc[x,i];
 77           a:=a+1 shl i;
 78         end;
 79 
 80     if d[y]>d[x] then
 81       for i:=20 downto 0 do
 82         if d[y]-1 shl i>=d[x] then
 83         begin
 84           y:=anc[y,i];
 85           b:=b+1 shl i;
 86         end;
 87 
 88     if x=y then exit;
 89     for i:=20 downto 0 do
 90       if (anc[x,i]<>anc[y,i]) then
 91       begin
 92         x:=anc[x,i]; a:=a+1 shl i;
 93         y:=anc[y,i]; b:=b+1 shl i;
 94       end;
 95 
 96     if (anc[x,0]=anc[y,0]) and (anc[x,0]<>0) then
 97     begin
 98       inc(a); inc(b);
 99       exit;
100     end;
101     num:=s[be[x]];
102     if c[x]>c[y] then a1:=a+num-c[x]+c[y] else a1:=a+c[y]-c[x];
103     b1:=b;
104     a2:=a;
105     if c[x]<c[y] then b2:=b+num-c[y]+c[x] else b2:=b+c[x]-c[y];
106     if max(a1,b1)=max(a2,b2) then
107     begin
108       if (min(a1,b1)>min(a2,b2)) or (min(a1,b1)=min(a2,b2)) and (a1<b1) then
109       begin
110         a:=a2;
111         b:=b2;
112       end
113       else begin
114         a:=a1;
115         b:=b1;
116       end;
117     end
118     else if max(a1,b1)>max(a2,b2) then
119     begin
120       a:=a2;
121       b:=b2;
122     end
123     else begin
124       a:=a1;
125       b:=b1;
126     end;
127   end;
128 
129 begin
130   readln(n,m);
131   for i:=1 to n do
132   begin
133     read(w[i]);
134     add(w[i],i);
135   end;
136 
137   for i:=1 to n do
138     if be[i]=0 then
139     begin
140       inc(t);
141       be[i]:=t;
142       x:=i;
143       while true do
144       begin
145         x:=w[x];
146         if be[x]=t then break;
147         be[x]:=t;
148       end;
149       y:=x;
150       r:=0;
151       repeat
152         inc(s[t]);
153         c[y]:=s[t];
154         inc(r);
155         q[r]:=y;
156         v[y]:=true;
157         y:=w[y];
158       until y=x;
159       bfs;
160     end;
161 
162   for i:=1 to m do
163   begin
164     readln(x,y);
165     if be[x]<>be[y] then
166     begin
167       writeln('-1 -1');
168       continue;
169     end;
170     lca(x,y);
171     writeln(a,' ',b);
172   end;
173 end.
View Code

 

转载于:https://www.cnblogs.com/phile/p/4552804.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BZOJ 2908 题目是一个数据下载任务。这个任务要求下载指定的数据文件,并统计文件中小于等于给定整数的数字个数。 为了完成这个任务,首先需要选择一个合适的网址来下载文件。我们可以使用一个网络爬虫库,如Python中的Requests库,来帮助我们完成文件下载的操作。 首先,我们需要使用Requests库中的get()方法来访问目标网址,并将目标文件下载到我们的本地计算机中。可以使用以下代码实现文件下载: ```python import requests url = '目标文件的网址' response = requests.get(url) with open('本地保存文件的路径', 'wb') as file: file.write(response.content) ``` 下载完成后,我们可以使用Python内置的open()函数打开已下载的文件,并按行读取文件内容。可以使用以下代码实现文件内容读取: ```python count = 0 with open('本地保存文件的路径', 'r') as file: for line in file: # 在这里实现对每一行数据的判断 # 如果小于等于给定整数,count 加 1 # 否则,不进行任何操作 ``` 在每一行的处理过程中,我们可以使用split()方法将一行数据分割成多个字符串,并使用int()函数将其转换为整数。然后,我们可以将该整数与给定整数进行比较,以判断是否小于等于给定整数。 最后,我们可以将统计结果打印出来,以满足题目的要求。 综上所述,以上是关于解决 BZOJ 2908 数据下载任务的简要步骤和代码实现。 希望对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值