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 


problem-solving report: This topic is one of the longest path to be solved, only to let him go next in the premise of each side, walked right point and the maximum value.
After make good use of vector storage, use dfs to burst search can be, there is a small optimization operations, we opened a s array is used to store
the current value of this node went right to the point on the path to a dead end and, the rest of the violence can be found.

ac Code:
#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]) // if u through this point, it is explained v arriving 
        {
             IF (u = pre [v]!) // If v is not the father node u, then v is not a dead end 
            { 
                Mark [v] = . 1 ; 
            } 
        } 
        the else // before this point there has been no u access 
        { 
            pre [u] = V; // then u is the father node V 
            dfs (u); // continue as a starting point u to dfs 
            IF (Mark [u]) Mark [V] = . 1 ; //If the search later in the u can continue to develop, it is not a dead end, then v is not a dead end 
            the else S [v] = max (S [u], S [v]); // If u is no way to continue to develop , then that is a dead end 
        } 
    } 
    IF (! Mark [V]) 
        S [V] + = W [V]; // if it is a dead end, then all points on the right path plus dead end and 
    return ; 
} 

int main () 
{ 
    int n-, m; 
    CIN >> >> n- m;
     for ( int I = . 1 ; I <= n-; I ++ ) 
    { 
        CIN >> W [I];     
    }     
    Memset (S, 0 , the 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;
}

 



Guess you like

Origin www.cnblogs.com/Spring-Onion/p/11594902.html