zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Yii2的相关学习记录,后台模板和gii(三)
    Yii2的相关学习记录,初始化Yii2(二)
    Yii2的相关学习记录,下载Yii2(一)
    虚拟机上网总结
    纯Java实现微信朋友圈分享图
    【集合框架】JDK1.8源码分析之ArrayList详解(一)
    Java中字符串相加和字符串常量相加区别
    onTouchEvent中,跟随手指滑动的view出现抖动
    Android CHM文件阅读器
    CHM格式
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3650562.html
Copyright © 2011-2022 走看看