zoukankan      html  css  js  c++  java
  • APIO2009 抢掠计划

    传送门

    这道题是个Tarjan+DAG上求最长路的好题啊……来说说我的智障做法。

    首先这题很明显要缩点,这都没啥,然后我发现要求最长路?

    好啊,直接找昨天学的那种,深搜!过了样例就交。

    算法一,期望得分100,实际得分7.

    ???好的,发现这个算的是从一个点出发的最长路,我们要求的是终点还必须是酒馆的一条路径,于是乎有了算法二:从每个点倒着往回跑最长路,遇到出发点就停!

    算法二,期望得分100,实际得分87.(好吧其实是没卡我)

    仔细想了一下发现,好像反着跑的话你可以一直不经过起点,这样不符合要求……

    然后想了一下,就又有了算法三:先在正图上把所以起点能到的点都跑出来,这些之中的点再往回跑!

    算法三:期望得分100,实际得分75.(?????)

    好吧后来发现,这样反着往回跑的话,你还是有可能不经过起点。

    于是乎最后只好直接用SPFA跑最长路了……这次终于得到了期望的100分……

    看一下代码。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    using namespace std;
    typedef long long ll;
    const int M = 5000005;
    const int N = 10000005;
     
    int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
        if(ch == '-') op = -1;
        ch = getchar();
        }
        while(ch >='0' && ch <= '9')
        {
        ans *= 10;
        ans += ch - '0';
        ch = getchar();
        }
        return ans * op;
    }
    
    struct edge
    {
        int next,to,from,v;
    }e[M],e1[M];
    
    int head[M],dis[M],n,m,ecnt,ecnt1,low[M],dfn[M],idx,cnt,val[M],sval[M],maxn,x,y,s,p,belong[M];
    int stack[M],top,head1[M];
    bool bar[M],bar1[M],vis[M],pd[M];
    
    void add(int x,int y)
    {
        e[++ecnt].to = y;
        e[ecnt].from = x;
        e[ecnt].next = head[x];
        head[x] = ecnt;
    }
    
    void add1(int x,int y,int z)
    {
        e1[++ecnt1].to = y;
        e1[ecnt1].from = x;
        e1[ecnt1].v = z;
        e1[ecnt1].next = head1[x];
        head1[x] = ecnt1;
    }
    
    void tarjan(int x)
    {
        low[x] = dfn[x] = ++idx;
        vis[x] = 1,stack[++top] = x;
        for(int i = head[x];i;i = e[i].next)
        {
        if(!dfn[e[i].to]) tarjan(e[i].to),low[x] = min(low[x],low[e[i].to]);
        else if(vis[e[i].to]) low[x] = min(low[x],dfn[e[i].to]);
        }
        if(dfn[x] == low[x])
        {
        cnt++;
        int p;
        while((p = stack[top--]))
        {
            belong[p] = cnt,vis[p] = 0;
            sval[cnt] += val[p];
            if(bar[p]) bar1[cnt] = 1;
            if(p == x) break;
        }
        }
    }
    
    void rebuild()
    {
        add1(0,belong[s],sval[belong[s]]);
        rep(i,1,ecnt)
        {
        int r1 = belong[e[i].from],r2 = belong[e[i].to];
        if(r1 != r2) add1(r1,r2,sval[r2]);
        }
    }
    
    void spfa()
    {
        queue <int> q;
        dis[0] = 0,q.push(0);
        while(!q.empty())
        {
        int k = q.front();q.pop();vis[k] = 0;
        for(int i = head1[k];i;i = e1[i].next)
        {
            if(dis[e1[i].to] < dis[k] + e1[i].v)
            {
            dis[e1[i].to] = dis[k] + e1[i].v;
            if(!vis[e1[i].to]) vis[e1[i].to] = 1,q.push(e1[i].to);
            }
        }
        }
    }
    
    int main()
    {
        n = read(),m = read();
        rep(i,1,m) x = read(),y = read(),add(x,y);
        rep(i,1,n) val[i] = read();
        s = read();
        rep(i,1,n) if(!dfn[i]) tarjan(i);
        rebuild();
        spfa();
        p = read();
        rep(i,1,p) x = read(),maxn = max(maxn,dis[belong[x]]);
        printf("%d
    ",maxn);
        return 0;
    }
  • 相关阅读:
    ES5新特性:理解 Array 中增强的 9 个 API
    ios
    Jquery异步 Deferred Object
    ES5中新增的Array方法详细说明
    Chart
    Angular常用语句
    vticker.js--垂直滚动插件
    <css系列>之css--float总结
    理解boot.img与静态分析Android/linux内核
    理解竞争条件( Race condition)漏洞
  • 原文地址:https://www.cnblogs.com/captain1/p/9716355.html
Copyright © 2011-2022 走看看