题意:
一个人在原点s,每个城市有对应的评价值w,不能走上次刚走的点,
比如最开始从6-2,下一次不能立即从2-6,但可以通过绕一圈6-2-1-3-4-2-6的方式回到6,意味着每个节点每条边都有可能经过多次,每个节点只算第一次经过时候的值。
求他在整个图中经过的城市累积的评价值的最大值。
 既然可以转圈圈,首先对强连通分量缩点,
缩完点之后第一次dfs预处理每个点的val值,对每个点,只要他的后代结点有环,就可以到达后代结点并回来,
那么后代结点的值直接累加到该点,对后代节点置零。
第二次dfs就是普通树上dp,因为到现在就是选择哪条链的问题。
还有模一下tarjan,一次dfs又能求lca又能求强连通分量%%%%%
用tarjan求强连通分量之后编个号就好了,,意外的好操作呢。。
#include <bits/stdc++.h>
using namespace std;
#define endll '\n'
#define C getchar()
typedef __int64 lll;
typedef long long ll;
#define pi acos(-1.0)
#define INF 0x3f3f3f3f
#define mod 1000000007
#define pii pair<int, int>
const int MAXN = 1e6 + 10;
#define stop system("pause")
#define lowbit(x) ((x) & (-x))
#define Temp template <typename T>
#define mem(a, b) memset(a, b, sizeof(a))
#define fast ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
Temp inline void rd(T &s)
{
    s = 0;T t = 1, k = C;
    for (; k < '0' || k > '9'; k = C)if (k == '-') t = -1;
    for (; k >= '0' && k <= '9'; k = C) s = (s << 1) + (s << 3) + (k ^ 48);
    s *= t;
}
//
int n,m,s;
int w[MAXN];
vector<int>mp[MAXN],vc[MAXN];
//trajan
int tot;
int id[MAXN];
int top,sta[MAXN],ins[MAXN];//模拟栈
int cnt,dfn[MAXN],low[MAXN];//结点编号及该点所在的强连通分量最小编号
//dfs
int sz[MAXN];//该点为多个点缩成
ll dp[MAXN],val[MAXN];
void tra(int x,int fa)
{
    low[x]=dfn[x]=++cnt;//
    sta[++top]=x;ins[x]=1;
    for(int i=0;i<mp[x].size();++i)
    {
        int v=mp[x][i];
        if(v==fa) continue;
        if(!dfn[v])
            tra(v,x),low[x]=min(low[x],low[v]);
        else if(ins[v])
            low[x]=min(low[x],dfn[v]);
    }
    if(low[x]==dfn[x])
    {
        tot++;//新图对应编号
        while(1)
        {
            int j=sta[top--];
            id[j]=tot;
            ins[j]=0;
            sz[tot]++;
            val[tot]+=w[j];
            ins[j]=0;
            if(j==x) break;
        }
    }
}
void dfs1(int u,int fa)//如果一个点的儿子结点有环,那么可以可以走到并且可以回来
{
    for(int i=0;i<vc[u].size();++i)
    {
        int v=vc[u][i];
        if(v==fa) continue;
        dfs1(v,u);
        if(sz[v]>1)
        {
            val[u]+=val[v];
            sz[u]+=sz[v];
            val[v]=0;
        }
    }
}
void dfs(int u,int fa)
{
    for(int i=0;i<vc[u].size();++i)
    {
        int v=vc[u][i];
        if(v==fa) continue;
        dfs(v,u);
        dp[u]=max(dp[u],dp[v]);
    }
    dp[u]+=val[u];
}
int main()
{
    rd(n),rd(m);
    for(int i=1;i<=n;++i) rd(w[i]);
    for(int i=0;i<m;++i)
    {
        int u,v;rd(u),rd(v);
        mp[u].push_back(v),mp[v].push_back(u);
    }
    rd(s);
    //缩点
    cnt=tot=top=0;
    tra(1,0);
    for(int u=1;u<=n;u++)//建新图
    {
        for(int i=0;i<mp[u].size();++i)
        {
            int v=mp[u][i];
            if(id[v] == id[u]) continue;
            vc[id[u]].push_back(id[v]);
        }
    }
    //
    dfs1(id[s],-1);
    dfs(id[s],-1);
    printf("%lld\n",dp[id[s]]);
    //stop;
    return 0;
}