题解 P1477 [NOI2008] 假面舞会
洛谷。
题意
一共 $n$ 个人,一共 $m$ 条消息,$k$ 种面具。
第 $i$ 种面具可以看到第 $i+1$ 种面具,第 $k$ 种面具可以看到第 $1$ 种面具。
每条消息表示 $u$ 能看到 $v$。
问 $k$ 的最大值以及 $k$ 的最小值,并且 $k\ge 3$。
分析
首先,我们以此建图,分析一下性质。
先一步一步说结论,然后分析吧。
首先,假如说存在环,那么我们的 $k$ 必然是其长度的因数。
为什么呢,因为我们的最重要的性质就是我们第 $i$ 种可以看到 $i+1$,所以我们的种类其实也是会形成一个环的。然而我们遍历出的环的也是会经过许多轮 $k$ 的环,所以结论就可以得出了。
然而倘若存在许多个环呢,由于我们的 $k$ 是其中每一个的因子,所以 $k$ 此时就是每一个环的 $\gcd$。
第二种,就是两条首、尾相同的链。
与第一种相似的,我们长的那条链必然也是短的那条链的不断重复。所以,$k$ 也是两条链的长度差的因子。
第三种,不存在前两种。
不存在前两种,我们已经没有了数字因子上的约束。
因而,我们只有极值上的范围。
因为我们的每一种的面具必然是存在过的,所以,此时我们 $k$ 的最大值也就是每个联通块最长链的长度之和。
那我们应当如何解决呢,因为我们每一次应当处理完整一个联通块,因此,我们需要在遍历其中一个点时就将整个联通块遍历完,所以,我们将有向图转化成无向图,同时标记其是正边或是反边在转移时,将时间 $+1$ 或 $-1$ 即可。
至于我们这个联通块的最长链呢,就是最大的距离减去最小距离即可。
inline void dfs(int now,int T) {
if(mark[now]) {
if(T==vis[now]) return ;
if(!flag) mn=abs(T-vis[now]);
else mn=__gcd(mn,abs(T-vis[now]));
flag=1;
return ;
}
vis[now]=T,mark[now]=1;
MX=max(MX,T),MN=min(MN,T);
for(auto it:lj[now]) dfs(it.to,T+it.w);
}

浙公网安备 33010602011771号