Codeforces Round #586 (Div. 1 + Div. 2) E. Tourism

https://codeforces.com/contest/1220/problem/E

//思路:由题可知,不能往回走,因此先找出所有的叶子节点,从叶子节点往root根节点去搜索,碰见环则停止,因为在环中的节点是一定可以相互到达的,因此就不会存在一个选择问题

//最后把所有环中的节点w[i]累加和能到达的一条最大支路算出即可

#include<bits/stdc++.h>
using namespace std;
typedef long long i64;
const int maxn = 2e5 + 32;
int wi[maxn],edge[maxn];
i64 cnt[maxn];
queue<int> q;
vector<int> Grape[maxn];
int main()
{
    ios::sync_with_stdio(false); cin.tie(0),cout.tie(0);
    int n,m,u,v,root;
    cin>>n>>m;
    for(int i=1;i<=n;++i)
        cin>>wi[i];
    for(int i=1;i<=m;++i)
    {
        cin>>u>>v;
        Grape[u].push_back(v);
        Grape[v].push_back(u);
        ++edge[u],++edge[v];
    }
    cin>>root;
    for(int i=1;i<=n;++i)
        if(edge[i] == 1&&i != root)
            q.push(i);//放入叶子节点
    while(!q.empty())
    {
        int u = q.front();  q.pop();
        edge[u] = -1;
        for(auto nxt: Grape[u])
        {
            if(edge[nxt] == -1)
                continue;
            --edge[nxt];
            cnt[nxt] = max(cnt[nxt],cnt[u]+wi[u]);
            if(edge[nxt] == 1&& nxt != root)
                q.push(nxt);
        }
    }
    i64 sum = 0,maxValue = 0;
    for(int i=1;i<=n;++i)
        if(edge[i]!=-1)
        {
            sum += wi[i];
            maxValue = max(maxValue,cnt[i]);
        }
    cout<<sum + maxValue <<'\n';
}

 

posted on 2019-10-06 17:12  chengyulala  阅读(134)  评论(0编辑  收藏  举报

导航