题解 P4974 【毒瘤之神秘通道】
自己的题怎么能不发篇题解呢qwq
(出题人自己觉得实际上可以用树剖的)
然后CYJian大佬一看:
“这不就是两遍拓补排序吗....”
经过了这段话后...我是豁然开朗......
#include <bits/stdc++.h>
#define reg register
#define ge getchar()
#define Num(a) isdigit(a)
#define maxn 2000000
inline long long read() {
reg long long x = 0, ch = ge;
while(!Num(ch)) ch = ge;
while(Num(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = ge;
return x;
}
inline long long min(long long a,long long b){return a>b?b:a;}
int n, m,from[maxn + 1],gotoo[maxn + 1];
long long dis[maxn + 1],s[maxn + 1],q[maxn + 1];
int main() {
n = read(), m = read();
for(reg int i=1;i<=n;i++)
++from[gotoo[i]=read()];
for(reg int i=1;i<=m;i++)
++from[gotoo[i+n]=read()],dis[i+n]=read();
reg int x,L=1,R=0,Top=0;
for(x=1;x<=m;++x)
q[++R] = x + n;
for(x=1;x<=n;++x)
if(!from[x])q[++R]=x;
while(L<=R) {
s[++Top] = x = q[L++];
if(!gotoo[x]) continue;
--from[gotoo[x]];
if(!from[gotoo[x]]) q[++R]=gotoo[x];
dis[gotoo[x]]+=dis[x];
}
while(gotoo[s[Top]]==0)--Top;
while(Top)x=s[Top--],dis[x]+=dis[gotoo[x]];
reg long long res=2147483647LL*2147483647LL;
reg int pos = 0;
for(reg int i = 1; i <= m; i++) {
res=min(res,dis[gotoo[i+n]]);
if(dis[gotoo[i+n]]==res)
pos=gotoo[i+n];
}
printf("%d %lld", pos, res);
return 0;
}
代码略丑请见谅....