AcWing
  • 首页
  • 活动
  • 题库
  • 竞赛
  • 校园
  • 应用
  • 文章
    • 题解
    • 分享
    • 问答
  • 吐槽
  • 登录/注册

AcWing 1207. 大臣的旅费(反证法的解析)    原题链接    中等

作者: 作者的头像   qiao ,  2022-01-24 17:44:28 ,  所有人可见 ,  阅读 51


0


反证法:
步骤:想要证明P
(1)证明!p为F(!P与事实矛盾)
(2)所以p为T,证毕

证明:P为F(P与事实矛盾)
只需找出一种与事实相反具体情况,
就能证明P为F
(要证明P为T则需要P的全部情况均为T,
而要证明P为F则仅需要P的一种情况为F即可)

14E9ACAB53A9A3388A33C655E46357B8.png

C++ 代码

#include<bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;
typedef long long LL;

struct Node
{
    int id, w;
};

vector<Node> g[N];//邻接表
int dist[N];//当前点到某点的距离
int n;

void dfs(int u, int f, int d)
{
    dist[u] = d;
    for (auto x : g[u])//遍历邻接表(g[u]之外的结点是当前结点不能一次到达的结点)
    {
        if (x.id != f)dfs(x.id, u, d+x.w);
    }
}

LL f(int len)
{
    return 10 * len + (1LL + len) * len / 2;
}

int main()
{
    cin >> n;
    for (int i = 0; i < n-1; i++)
    {
        int p, q, d; scanf("%d%d%d", &p, &q, &d);
        g[p].push_back({ q,d });
        g[q].push_back({ p,d });
        //无向图
    }

    //找到树直径的a端点
    dfs(1, -1, 0);

    int a = 1;
    for (int i = 1; i <= n; i++)
    {
        if (dist[i] > dist[a])a = i;
    }

    dfs(a, -1, 0);

    //找到树直径的b端点
    int b = 1;
    for (int i = 1; i <= n; i++)
    {
        if (dist[i] > dist[b])b = i;
    }

    int len = dist[b];//因为第二次dfs是以a为起点
    //所以dist[b]的含义是a到b的距离

    printf("%lld", f(len));

}

0 评论

你确定删除吗?
1024
x

© 2018-2022 AcWing 版权所有  |  京ICP备17053197号-1
用户协议  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标
请输入绑定的邮箱地址
请输入注册信息