• bzoj 1179 tarjan+spfa


      首先我们可以将这个图缩成DAG,那么问题中的路线就可以简化为DAG中的一条链,那么我们直接做一遍spfa就好了。

      反思:开始写的bfs,结果bfs的时候没有更新最大值,而是直接赋的值,后来发现不能写bfs,因为每个点可能进队好多次,当让可以改成循环队列什么的bfs,然后我就改成了spfa,伪的spfa,就是判一下这个点是不是更优了,更优才入队。

    /**************************************************************
        Problem: 1179
        User: BLADEVIL
        Language: C++
        Result: Accepted
        Time:6640 ms
        Memory:109356 kb
    ****************************************************************/
     
    //By BLADEVIL
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define maxm 2000010
    #define maxn 2000010
     
    using namespace std;
     
    int n,m,s,tot,time,num,p,l;
    int pre[maxm],other[maxm],last[maxn],key[maxn],flag[maxn];
    int stack[maxn],dfn[maxn],low[maxn],vis[maxn],col[maxn],que[maxn],w[maxn];
     
    void connect(int x,int y) {
        pre[++l]=last[x];
        last[x]=l;
        other[l]=y;
    }
     
    void dfs(int x) {
        stack[++tot]=x; vis[x]=1;
        dfn[x]=low[x]=++time;
        for (int p=last[x];p;p=pre[p]) {
            if (!dfn[other[p]]) 
                dfs(other[p]),low[x]=min(low[x],low[other[p]]); else
            if (vis[other[p]]) low[x]=min(low[x],dfn[other[p]]);
        }
        if (dfn[x]==low[x]) {
            int cur=-1;
            num++;
            while (cur!=x) {
                cur=stack[tot--];
                vis[cur]=0;
                col[cur]=num;
            }
        }
    }
     
    int main() {
        scanf("%d%d",&n,&m); num=n;
        for (int i=1;i<=m;i++) {
            int x,y; scanf("%d%d",&x,&y);
            connect(x,y);
        }
        for (int i=1;i<=n;i++) scanf("%d",&key[i]);
        scanf("%d%d",&s,&p);
        while (p--) {
            int x; scanf("%d",&x);
            flag[x]=1;
        }
        dfs(s);
        for (int i=1;i<=n;i++) {
            for (int p=last[i];p;p=pre[p]) if (col[i]!=col[other[p]]) connect(col[i],col[other[p]]);
        }
        for (int i=1;i<=n;i++) key[col[i]]+=key[i],flag[col[i]]|=flag[i];
        memset(vis,0,sizeof vis);
        que[1]=col[s]; vis[col[s]]=1; w[col[s]]=key[col[s]];
        int h=0,t=1,ans=0;
        while (h<t) {
            int cur=que[++h];
            if (flag[cur]) ans=max(ans,w[cur]);
            for (int p=last[cur];p;p=pre[p]) {
                if (w[cur]+key[other[p]]>w[other[p]]) {
                w[other[p]]=max(w[other[p]],w[cur]+key[other[p]]);
                que[++t]=other[p]; vis[other[p]]=1;
                }
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    什么是跨域
    w3c标准
    什么是域名?什么网站名?什么是URL?
    meta是什么意思?
    什么是HTML、XML和XHTML
    html4.0.1,h5,xhml,文档声明区别
    checkbox 点击全选
    【今日CV 计算机视觉论文速览】Fri, 22 Mar 2019
    【机器翻译】API接口总结
    【今日CV 计算机视觉论文速览】Fri, 22 Mar 2019
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3650562.html
Copyright © 2020-2023  润新知