洛谷 P1416 攻击火星 排版重构

洛谷 P1416 攻击火星

原题P1416

Update

20210307 修复了挂掉的图片

20210307 重构排版

Solution

understand

首先,你弄明白了什么是度吗?

一个点的度,等于与它连接的边的数量。

那这题怎么模拟鸭?50000点,邻接表都开不了耶……

接着,我们从特殊到一般来构造这道题——

special situation

n=1

只有一个点,这个点一定会被删掉,ans=0

n=2

有了两个点,但是度数相同,都会被删掉,ans=0

n=3

样例中也是三个点,使用的是一条链的构造方法。

ans=1

欸?这个会不会是一个提示?

n=4

我们试试用一条链

img

也是这样最优,ans=4

难道说链就是正确的构造方法吗?

再试试吧

n=5

继续使用链:

由于删去了两个末端节点后,中间的那个节点的度仍为2。所以它会在d=2时被删去!

有没有一种方法,可以避免这种悲剧的发生呢?

当然有的!我们换一种构造方法。请看好了——

\(n=6\)为例:

选出两个末端节点------牺牲品

img

把两个末端节点与所有非末端节点相连

img

再把非末端节点与所有非末端节点相连(并标上每个点的度)

img

肯定是两个末端节点先被删除了

但是,当它们被删除时,其他所有的节点都会被改变!

完美的错过当前的d+1

img

这,就是本题的思想:

删去一些节点后,让其他节点的度都改变为那时的d

这样“其他节点”都不会狗带咯!

general situation

当有n个点时,取其中的两个节点当牺牲品。(所以\(n<2\)时 仍有ans=0

把两个末端节点与所有非末端节点相连

再把非末端节点与所有非末端节点相连

最终,

末端节点的度都等于n-2

非末端节点的度都等于n-1(除它本身以外全连)

那么末端节点会先被删除(\(d=n-2\)

同时,非末端节点的度-=2 -> n-3

这时,d++(\(d=n-1\)

非末端节点们就安全了!

如果还是不懂,欢迎评论!

Code

#include<iostream>
using namespace std;
int n;
int main()
{
    cin>>n;
    if(n==1) cout<<0;
    else cout<<n-2;
    //也可以是这样的
    /*
    cout<<max(n-2,0);
    */ 
    return 0;
}
posted @ 2021-03-07 19:00  Vanilla_chan  阅读(85)  评论(0编辑  收藏  举报