zoukankan      html  css  js  c++  java
  • [APIO 2009] Atm

    传送门:>Here<

    题意:给出一个有向图(有环),每个点有点权。从点S出发,经过每个点Tot可以加上点权,点可以经过多次,然而点权不能重复加多次。先要求走到某个终点E时点权最大。先要求在给定的某些终点E终,点权之和的最大值。

    解题思路:

      题目有点难懂。首先如果只是暴力搜索的话,由于有环会无限循环,而且环内的值只会加一次,很容易想到强连通分量缩点。然后SPFA(改一改,变成最大值)求出每个点的最大值就可以了。然而如果某一个强连通分量里有酒吧,那么走到这个强联通分量作为终点一定是可以的。因此加个判断就好了。还是很水的……

    Code

      Nothing

    /*By QiXingzhi*/
    #include <cstdio>
    #include <queue>
    #include <cstring>
    #define  r  read()
    #define  Max(a,b)  (((a)>(b)) ? (a) : (b))
    #define  Min(a,b)  (((a)<(b)) ? (a) : (b))
    typedef long long ll;
    using namespace std;
    const int MAXN = 500010;
    const int MAXM = 1000010;
    const int INF = 0x3f3f3f3f;
    inline int read(){
        int x = 0; int w = 1; register int c = getchar();
        while(c ^ '-' && (c < '0' || c > '9')) c = getchar();
        if(c == '-') w = -1, c = getchar();
        while(c >= '0' && c <= '9') x = (x << 3) +(x << 1) + c - '0', c = getchar();
        return x * w;
    }
    bool bar[MAXN];
    queue <int> q;
    vector <int> G[MAXN],G2[MAXN];
    int N,M,dfs_clock,S,P,scc_cnt,top,_x,ans;
    int p[MAXN],sccno[MAXN],dfn[MAXN],low[MAXN],sta[MAXN],x[MAXN],y[MAXN],d[MAXN],val[MAXN],win[MAXN];
    inline void AddEdge(int u, int v){ G[u].push_back(v); }
    inline void AddEdge2(int u, int v){ G2[u].push_back(v); }
    inline void tarjan(int u){
        dfn[u] = low[u] = ++dfs_clock;
        sta[++top] = u;
        int sz = G[u].size(), v;
        for(int i = 0; i < sz; ++i){
            v = G[u][i];
            if(!dfn[v]){ tarjan(v); low[u] = Min(low[u], low[v]); }
            else if(!sccno[v]) low[u] = Min(low[u], dfn[v]);
        }
        int X;
        if(dfn[u] == low[u]){
            ++scc_cnt;
            while(1){
                X = sta[top--];
                if(bar[X]) win[scc_cnt] = 1;
                sccno[X] = scc_cnt;
                val[scc_cnt] += p[X];
                if(X == u) break;
            }
        }
    }
    inline void BFS(int s){
        d[s] = val[s];
        q.push(s);
        int cur,sz,v;
        while(!q.empty()){
            cur = q.front(), q.pop();
            sz = G2[cur].size();
            for(int i = 0; i < sz; ++i){
                v = G2[cur][i];
                if(d[cur] + val[v] > d[v]){ d[v] = d[cur] + val[v]; q.push(v); }
            }
        }
    }
    int main(){
        N = r, M = r;
        for(int i = 1; i <= M; ++i){ x[i] = r, y[i] = r; AddEdge(x[i], y[i]); }
        for(int i = 1; i <= N; ++i) p[i] = r;
        S = r, P = r;
        for(int i = 1; i <= P; ++i) _x = r, bar[_x] = 1;
        for(int i = 1; i <= N; ++i) if(!dfn[i]) tarjan(i);
        for(int i = 1; i <= M; ++i) if(sccno[x[i]] != sccno[y[i]]) AddEdge2(sccno[x[i]], sccno[y[i]]);
        BFS(sccno[S]);
        for(int i = 1; i <= N; ++i) if(win[i]) ans = Max(ans, d[i]);
        printf("%d", ans);
        return 0;
    }
  • 相关阅读:
    iOS UITextField限制输入长度
    SpringBoot 统一异常处理
    idea+springboot+freemarker热部署
    JAVA 实现链表
    mysql 添加新用户 赋予权限
    Spring MVC 集成 Redis集群
    js获取当前日期时间及其它操作
    MySQL Error Codes MYSQL的错误代码
    js数组 删除元素
    JS table form 序列化提交
  • 原文地址:https://www.cnblogs.com/qixingzhi/p/9353337.html
Copyright © 2011-2022 走看看