zoukankan      html  css  js  c++  java
  • Tourism【codeforces 1200E】

    E. Tourism
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Alex decided to go on a touristic trip over the country.

    For simplicity let's assume that the country has nn cities and mm bidirectional roads connecting them. Alex lives in city ss and initially located in it. To compare different cities Alex assigned each city a score wiwi which is as high as interesting city seems to Alex.

    Alex believes that his trip will be interesting only if he will not use any road twice in a row. That is if Alex came to city vv from city uu, he may choose as the next city in the trip any city connected with vv by the road, except for the city uu.

    Your task is to help Alex plan his city in a way that maximizes total score over all cities he visited. Note that for each city its score is counted at most once, even if Alex been there several times during his trip.

    Input

    First line of input contains two integers nn and mm, (1n21051≤n≤2⋅105, 0m21050≤m≤2⋅105) which are numbers of cities and roads in the country.

    Second line contains nn integers w1,w2,,wnw1,w2,…,wn (0wi1090≤wi≤109) which are scores of all cities.

    The following mm lines contain description of the roads. Each of these mm lines contains two integers uu and vv (1u,vn1≤u,v≤n) which are cities connected by this road.

    It is guaranteed that there is at most one direct road between any two cities, no city is connected to itself by the road and, finally, it is possible to go from any city to any other one using only roads.

    The last line contains single integer ss (1sn1≤s≤n), which is the number of the initial city.

    Output

    Output single integer which is the maximum possible sum of scores of visited cities.

    Examples
    input
    Copy
    5 7
    2 2 8 6 9
    1 2
    1 3
    2 4
    3 2
    4 5
    2 5
    1 5
    2
    
    output
    Copy
    27
    
    input
    Copy
    10 12
    1 7 1 9 3 3 6 30 1 10
    1 2
    1 3
    3 5
    5 7
    2 3
    5 4
    6 9
    4 6
    3 7
    6 8
    9 4
    9 10
    6
    
    output
    Copy
    61


    解题报告:这个题目就是要求解最长的一个路径,让他在每条边只走一次的前提下,走过的点的权值之和最大。
    利用vector存储好以后,使用dfs去爆搜就可以,这里有一个小的操作的优化,就是开设了一个s数组,用来存放
    当前这个结点走到死胡同的路径上的点权值之和,剩下的暴力搜就可以。

    ac代码:
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    using namespace std;
    typedef long long ll;
    
    const int maxn=2e5+100;
    vector<int> edge[maxn];
    ll w[maxn],s[maxn];
    int mark[maxn],vis[maxn],pre[maxn];
    
    void dfs(int v)
    {
        vis[v]=1;
        for(int j=0;j<edge[v].size();j++)
        {
            int u=edge[v][j];
            if(vis[u])//如果u这个点走过,那么说明v是可到达的 
            {
                if(u!=pre[v])//如果v的父亲结点不是u的话,那么v不是死胡同的 
                {
                    mark[v]=1;
                }
            }
            else//之前u这个点没有进行过访问 
            {
                pre[u]=v;//那么u的父亲结点就是v 
                dfs(u);//继续进行dfs以u为起点 
                if(mark[u]) mark[v]=1;//如果u在之后的搜索中是可以继续开拓的,就不是死胡同,那么v也是不是死胡同 
                else s[v]=max(s[u],s[v]);//如果u是没有办法继续开拓的,那么就是死胡同了 
            }
        }
        if(!mark[v])
            s[v]+=w[v];//如果是死胡同,那么死胡同路径上的全部点权加和 
        return;
    }
    
    int main()
    {
        int n,m;
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        {
            cin>>w[i];    
        }    
        memset(s,0,sizeof(s));
        memset(mark,0,sizeof(mark));
        memset(vis,0,sizeof(vis));
        memset(pre,0,sizeof(pre));
        int u,v;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&u,&v);
            edge[u].push_back(v);
            edge[v].push_back(u);
        }
        int st;
        scanf("%d",&st);
        dfs(st);
    //    for(int i=1;i<=n;i++)
    //    {
    //        cout<<i<<" "<<s[i]<<endl;
    //    }
        ll ans=0,maxx=0;
        for(int i=1;i<=n;i++)
        {
            if(mark[i])
                ans+=w[i];
            maxx=max(maxx,s[i]);
        }
        ans+=maxx;
        cout<<ans<<endl;
    }


  • 相关阅读:
    PTA 7-29 修理牧场(Huffman树)
    全网最详细最好懂 PyTorch CNN案例分析 识别手写数字
    【Python Deap库】遗传算法/遗传编程 进化算法基于python DEAP库深度解析讲解
    【比较】遗传算法GA和遗传编程GP有什么不同?
    【python(deap库)实现】GEAP 遗传算法/遗传编程 genetic programming +
    【比较】粒子群算法PSO 和 遗传算法GA 的相同点和不同点
    【遗传编程/基因规划】Genetic Programming
    【经典大数据竞赛科普】泰坦尼克灾难 到底是个什么东西
    【Python代码】TSNE高维数据降维可视化工具 + python实现
    【python代码】 最大流问题+最小花费问题+python(ortool库)实现
  • 原文地址:https://www.cnblogs.com/Spring-Onion/p/11594902.html
Copyright © 2011-2022 走看看