zoukankan      html  css  js  c++  java
  • 【缩点】洛谷P3387

    SPFA的tarjan缩点 是真的慢很多 但是也是真的很好理解

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int maxn=100010;
    bool vis[maxn];
    int n,m,ans=0,cnt=0,tot=0,top=0,num=0;
    int u[maxn],v[maxn],head[maxn],low[maxn],dfn[maxn];
    int dis[maxn],Dis[maxn],stack[maxn],po[maxn],a[maxn];
    struct Edge{
        int next,to;
    }cute[maxn];
    
    void build(int x,int y)
    {
        cute[++tot].next=head[x];
        cute[tot].to=y;
        head[x]=tot;
    } 
    
    void tarjan(int x)
    {
        dfn[x]=low[x]=++num;
        stack[++top]=x;
        vis[x]=true;
        for(int i=head[x];i;i=cute[i].next)
        {
            int y=cute[i].to;
            if(vis[y]) low[x]=min(low[x],dfn[y]);
            else if(!dfn[y]) tarjan(y),low[x]=min(low[x],low[y]);
        }
        if(low[x]==dfn[x])
        {
            vis[x]=false;
            cnt++;
            while(stack[top+1]!=x)
            {
                po[stack[top]]=cnt;
                vis[stack[top]]=false;
                Dis[cnt]+=a[stack[top]];
                top--;
            }
        }
    }
    
    void Spfa(int x)
    {
        memset(vis,0,sizeof(vis));
        memset(dis,0,sizeof(dis));
        dis[x]=Dis[x];
        queue<int> q;
        vis[x]=true;
        q.push(x);
        while(!q.empty())
        {
            int u=q.front();
            vis[u]=false;
            q.pop();
            for(int i=head[u];i;i=cute[i].next)
            {
                int v=cute[i].to;
                if(dis[v]<dis[u]+Dis[v])
                {
                    dis[v]=dis[u]+Dis[v];
                    if(!vis[v])
                    {
                        vis[v]=true;
                        q.push(v); 
                    }
                }
            }
        }
        for(int i=1;i<=n;i++) ans=max(ans,dis[i]); 
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&u[i],&v[i]);
            build(u[i],v[i]);//有向图 建一次边
        }
        for(int i=1;i<=n;i++)
            if(!dfn[i]) tarjan(i);
        memset(head,0,sizeof(head));
        memset(cute,0,sizeof(cute));
        for(int i=1;i<=m;i++)
            if(po[u[i]]!=po[v[i]]) build(po[u[i]],po[v[i]]);
        for(int i=1;i<=n;i++) Spfa(i);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    SpringBoot之SpringApplication
    IP数据库
    Android长按及拖动事件探究
    5.7之sql_model
    Linux 信号介绍
    设计模式详解及PHP实现:代理模式
    为你的AliOS Things应用增加自定义cli命令
    DRDS SQL 审计与分析——全面洞察 SQL 之利器
    下一代大数据处理引擎,阿里云实时计算独享模式重磅发布
    2135亿背后的双11项目协作怎么玩?
  • 原文地址:https://www.cnblogs.com/Koiny/p/9879829.html
Copyright © 2011-2022 走看看