LuoguP6857 梦中梦与不再有梦 题解
Update
- \(\texttt{2020.10.20}\) 增加了证明。感谢@东北小蟹蟹(dbxxxqwq)的提醒。
Content
有一个 \(n\) 个点的无向图,每两个点之间都有一条边直接相连。你从 \(1\) 出发,每条边最多只能经过一次,当走到一个点,其相连的边都不能走时,你会停下来。问你最多能够经过多少条边。
数据范围:\(T\) 组数据,\(T\leqslant 10^5,n\leqslant 10^9\)。
Solution
我们先画图来找规律,先是 \(n=3\) 的,由样例可以直接得知,这个图里面的 \(3\) 条边都能够经过,答案是 \(3\)。
那么,我们再来画几个图找找规律,\(n=4\) 的时候的图是这样的:
自己走一下就可以发现,无论怎么样都有 \(1\) 条边走不了。
那么,\(n=5\) 的时候呢?
我们可以先走五角星状的路线,然后再走五边形状的路线,这样所有边都走得了。
再画一下 \(n=6\) 的图,走一下发现,无论怎么样都有 \(2\) 条边走不了。
然后这样我们得到一个规律:设答案为 \(ans\),则有:
\[ans=\begin{cases}\dfrac{n(n-1)}{2}&2\nmid n\\\dfrac{n(n-1)}{2}-\dfrac{n}{2}+1&2\mid n\end{cases}
\]
虽然是乱搞得出的规律,但我们惊喜的发现,交上去之后,这样的思路是对的!
乱搞搞完了,我们为什么不证明一下呢?
这道题目其实就是要我们找一个欧拉路径(不会欧拉路径?bfs一下你就知道)。如果是奇数个点的话,必定会形成一个欧拉回路,即存在一个能经过每条边一次并且仅一次的回路,那么也肯定就会有欧拉路径。如果是偶数个点的话,删任意 \(\dfrac{n}{2}-1\) 条边,没有公共顶点的边就可以使整张图变成半欧拉图,存在一条欧拉路径。
那么这样就证明完了,大概就是这样的一道找规律可以水过的题目,找到规律之后写代码挺简单的,但主要问题就是证明了。
Code
int t;
long long n;
int main() {
//This program is written in Windows 10 by Eason_AC
getint(t);
while(t--) {
getll(n);
n = n * (n - 1) / 2 - (!(n % 2) ? n / 2 - 1 : 0);
writell(n), puts("");
}
return 0;
}