【解题报告】Tree Destruction CodeForces - 911F(搜索??)

【解题报告】Tree Destruction CodeForces - 911F(搜索??)

====================================================================

【cf链接】

【vj链接】

======================================================================

题目

You are given an unweighted tree with n vertices. Then n - 1 following operations are applied to the tree. A single operation consists of the following steps:

  1. choose two leaves;
  2. add the length of the simple path between them to the answer;
  3. remove one of the chosen leaves from the tree.
    Initial

Obviously after n - 1 such operations the tree will consist of a single vertex.

Calculate the maximal possible answer you can achieve, and construct a sequence of operations that allows you to achieve this answer!

Input

The first line contains one integer number n (2 ≤ n ≤ 2·105) — the number of vertices in the tree.

Next n - 1 lines describe the edges of the tree in form ai, bi (1 ≤ ai, bi ≤ n, ai ≠ bi). It is guaranteed that given graph is a tree.

Output

In the first line print one integer number — maximal possible answer.

In the next n - 1 lines print the operations in order of their applying in format ai, bi, ci, where ai, bi — pair of the leaves that are chosen in the current operation (1 ≤ ai, bi ≤ n), ci (1 ≤ ci ≤ n, ci = ai or ci = bi) — choosen leaf that is removed from the tree in the current operation.

See the examples for better understanding.

Examples

input

3
1 2
1 3

output

3
2 3 3
2 1 1

input

5
1 2
1 3
2 4
2 5

output

9
3 5 5
4 3 3
4 1 1
4 2 2

====================================================================

题目大意

有棵树,按照某规律删除结点并得到一个值。
某规律:找俩点,删掉其中一个
一个值:每次操作找的那俩点的距离

样例输入

第一行:一个n,表示树上有几个点
第2-n行:两个数x,y,表示一条边

输出

第一行:刚刚说的那一个值
第2-n行:三个数x,y,z,x,y表示一条边,z表示删除的那个点

====================================================================

解题思路

如果已经有一条路径(直径)是最长的,那其他点的最长路径一定是到达直径的端点的

假设这两个点叫p1,p2
要求的一个值叫ans

  • 步骤一:找到最长路径(两次dfs)

(从一个点出发,找到它的最长路径,那另一个点一定属于直径的端点)

  • 步骤二:除最长路径上的点全部删掉
  • 步骤三:删掉直径

(步骤二三通过分别从p1,p2遍历得到长度dis[i],dis2[i],用d[i]表示在直径上的某点离p2的距离,然后遍历一次,回溯时删除)
(求ans的过程在遍历之前,直接加d[i]或dis[i]或dis2[i]即可)

===================================================================

AC代码

不建议看这个代码,太乱了,幸好是1A,不然都不知道怎么改……

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#define LL long long
#define maxn 200007
using namespace std;

vector <int> edge[maxn];
int dis[maxn],vis[maxn],d[maxn],p1,p2,dis2[maxn],print[maxn];//print是方便输出的,不影响做题
void dfs1(int x)//求x到各点的距离存在dis数组里
{
    for(int i=0;i<edge[x].size();i++)
    {
        if(!vis[edge[x][i]])
        {
            vis[edge[x][i]]=1;
            dis[edge[x][i]]=dis[x]+1;
            dfs1(edge[x][i]);
        }
    }
}
void dfs3(int x)//求x到各点的距离存在dis2数组里
{
    for(int i=0;i<edge[x].size();i++)
    {
        if(!vis[edge[x][i]])
        {
            vis[edge[x][i]]=1;
            dis2[edge[x][i]]=dis2[x]+1;
            dfs3(edge[x][i]);
        }
    }
}
int dfs2(int x)//求x到直径上各点的距离,存在d数组里
{
    if(x==p2) return d[x]=1;
    for(int i=0;i<edge[x].size();i++)
    {
        if(!vis[edge[x][i]])
        {
            vis[edge[x][i]]=1;
            if(dfs2(edge[x][i]))
            {
                d[x]=d[edge[x][i]]+1;
                return 1;
            }
        }
    }
    return 0;
}
int dfs4(int x)//输出除直径外的点
{//printf("A");
    for(int i=0;i<edge[x].size();i++)
    {//printf("B");
        if(!vis[edge[x][i]])
        {
            vis[edge[x][i]]=1;
            dfs4(edge[x][i]);
            if(d[edge[x][i]]==0)
            {//printf("D");
                if(dis[edge[x][i]]>=dis2[edge[x][i]]) printf("%d %d %d\n",p1,edge[x][i],edge[x][i]);
                else printf("%d %d %d\n",p2,edge[x][i],edge[x][i]);
            }

        }
    }
}
int main()
{
    int n,i,j,x,y,maxlen;
    scanf("%d",&n);
    for(i=1;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        edge[x].push_back(y);
        edge[y].push_back(x);
    }
    vis[1]=1;
    dis[1]=0;
    dfs1(1);
    maxlen=-1;
    for(i=1;i<=n;i++)
    {
        if(maxlen<dis[i])
        {
            maxlen=dis[i];
            p1=i;
        }
        vis[i]=0;
    }
    vis[p1]=1;
    dis[p1]=0;
    dfs1(p1);
    maxlen=-1;
    for(i=1;i<=n;i++)
    {
        if(maxlen<dis[i])
        {
            maxlen=dis[i];
            p2=i;
        }
        vis[i]=0;
    }
    //printf("p1=%d p2=%d \n",p1,p2);
    dfs2(p1);
    dis2[p2]=0;
    for(i=1;i<=n;i++)
        vis[i]=0;
    vis[p2]=1;
    dfs3(p2);
    LL ans=0;
    for(i=1;i<=n;i++)
    {
        //printf("%d %d %d\n",dis[i],dis2[i],d[i]);
        if(!d[i]) ans+=max(dis[i],dis2[i]);
        else ans+=d[i]-1,print[d[i]]=i;
    }
    printf("%lld\n",ans);
    for(i=1;i<=n;i++)
        vis[i]=0;
    vis[p1]=1;
    dfs4(p1);
    for(i=1;i<d[p1];i++)
    {
        printf("%d %d %d\n",p1,print[i],print[i]);//print记录的是那条直径
    }
    return 0;
}
<think> Hmm, the user is asking about the specific functionality of the `--revertTPer` parameter in the sedutil-cli tool. Interesting - they seem to be working with self-encrypting drives (SEDs) and need advanced management capabilities. From the provided reference [3], I recall sedutil is used to bypass TCG protocol restrictions when communicating with SED drives. The user's query suggests they're diving deep into drive security management. The mention of "revert" implies they might be troubleshooting or resetting drive configurations. Checking my knowledge base: The `--revertTPer` command specifically triggers the drive's factory reset process. This is a critical operation that wipes all encryption keys and authentication credentials. It's typically used when redeploying drives or recovering from forgotten credentials. I should emphasize the irreversible nature of this command - it's essentially cryptographic scorched earth. The drive will behave like new out-of-box afterwards. The user seems technically proficient given they're using CLI tools directly, so I'll include the technical TCG term "PSID Revert" but also explain its consequences plainly. Potential concerns: The user didn't mention backup precautions. Since this nukes all data, I should strongly warn about data destruction despite it being obvious to professionals. Also worth noting any hardware-specific considerations? Most modern SEDs support this uniformly. The references show the user has been exploring related tools (redis-cli, sequelize-cli), suggesting they're comfortable with command-line interfaces across domains. No need to explain basic CLI concepts. Should focus purely on the cryptographic implications here. </think> 根据 SEDutil 工具的官方文档及相关技术资料,`--revertTPer` 参数的功能和注意事项如下: ### `--revertTPer` 参数的功能 1. **执行工厂重置(Factory Reset)** - 永久擦除驱动器的 **所有加密密钥**(包括用户数据和认证凭证) - 将 TCG Opal/SED 硬盘恢复到 **出厂初始状态**,清除所有安全配置[^3] 2. **PSID 授权操作** - 必须配合物理硬盘标签上的 **PSID(Physical Security ID)** 使用 - 命令格式: ```bash sedutil-cli --revertTPer <PSID> /dev/sdX ``` - 输入错误的 PSID 会导致操作失败(PSID 通常位于硬盘标签或包装盒上)[^3] 3. **适用场景** - 遗忘管理员密码时的紧急恢复 - 需要重新部署硬盘前的安全擦除 - 解除因多次密码错误触发的驱动器锁定[^3] ### ️ 重要警告 1. **不可逆操作** 执行后将永久丢失所有数据且无法恢复(包括加密数据) 2. **物理访问要求** 必须直接连接目标硬盘(不适用于远程操作) 3. **硬件兼容性** 仅支持符合 TCG Opal 2.0 标准的自加密硬盘(SED) --- ### 操作示例流程 ```bash # 1. 查看硬盘标识 sedutil-cli --scan # 2. 执行还原 (假设PSID为ABC123, 目标硬盘为sdb) sedutil-cli --revertTPer ABC123 /dev/sdb # 3. 等待返回 "Revert TPer SUCCESS" 提示 ``` > **注意**:此操作需在系统关机状态下进行,部分企业级硬盘需配合特定硬件指令(如 SAS 硬盘的 `--lr` 参数)[^3]。 --- ### 相关问题 1. `--revertTPer` 和普通格式化有何本质区别? 2. PSID 丢失后如何恢复 SED 硬盘的访问权限? 3. 执行 `--revertTPer` 后是否影响硬盘性能或寿命? [^3]: Sedutil 官方文档明确说明,`--revertTPer` 属于高风险操作,必须在物理接触设备且明确数据可销毁的前提下执行。此操作直接调用硬盘固件的底层重置指令,绕过所有软件层加密逻辑。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值