zoukankan      html  css  js  c++  java
  • a_lg_逃学小孩(spfa求树直径)

    Chris的父母会遵守以下规则:如果A距离C比B距离C近,那么C的父母先去A家寻找C,如果找不到,C的父母再去B家;反之亦然。
    但由于他并不知道A,B,C的具体位置,所以现在他希望你告诉他,最坏情况下Chris的父母要耗费多长时间才能找到Chris?

    思路
    求出树的直径的端点A、B,在一定存在某个点C,使得 A->B+min(C->A, C->B) 为答案

    • A->B为直径(不变)
    • C->A, C->A 为题目中的规则(A距离C比B距离C近的话,则优先去A,即在A、B中选最小者),但又由于是最坏情况,所以还需要跳出最小者中的最大值
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll N=2e6+5,inf=0x3f3f3f3f;
    int n,m,inq[N];
    struct node {
        ll u,w;
    };
    vector<node> g[N];
    int spfa(int s, vector<ll>& d) {
        memset(inq,false,sizeof inq);
        queue<int> q; q.push(s), d[s]=0;
        while (!q.empty()) {
            int u=q.front();
            q.pop(), inq[u]=false;
            for (auto& to : g[u]) {
                int v=to.u, w=to.w;
                if (d[v]>d[u]+w) {
                    d[v]=d[u]+w;
                    if (!inq[v]) {
                        q.push(v);
                        inq[v]=1;
                    }
                }
            }
        }
        ll mx=0, ans=0;
        for (int i=1; i<=n; i++) if (d[i]>mx) {
            mx=d[i], ans=i;
        }
        return ans;
    }
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        cin>>n>>m;
        for (int i=0; i<m; i++) {
            int u,v,w; cin>>u>>v>>w;
            g[u].push_back({v,w});
            g[v].push_back({u,w});
        }
        vector<ll> d1(n+1,inf*inf), d2(n+1,inf*inf);
        int A=spfa(1,d1);
        d1=vector<ll>(n+1,inf*inf);
        int B=spfa(A,d1);   //A->B即直径
        spfa(B,d2);
        ll zj=*max_element(d1.begin()+1, d1.end()), maxD=0;
        for (int C=1; C<=n; C++) {
            maxD=max(maxD,min(d1[C],d2[C]));
        }
        cout<<zj+maxD;
        return 0;
    }
    
  • 相关阅读:
    Windows性能计数器应用
    Azure Oracle Linux VNC 配置
    Azure 配置管理系列 Oracle Linux (PART6)
    Azure 配置管理系列 Oracle Linux (PART5)
    Azure 配置管理系列 Oracle Linux (PART4)
    Azure 配置管理系列 Oracle Linux (PART3)
    Azure 配置管理系列 Oracle Linux (PART2)
    vagrant多节点配置
    docker基本操作
    LINUX开启允许对外访问的网络端口命令
  • 原文地址:https://www.cnblogs.com/wdt1/p/13820703.html
Copyright © 2011-2022 走看看