zoukankan      html  css  js  c++  java
  • P3387 【模板】缩点

    P3387 【模板】缩点

    题解

    QWQ论这个题我开了多少数组QWQ

    因为每个点走过多次权值只会计算1次

    简化问题:把题目给出的有向图缩点,成为有向无环图,然后拓扑排序跑最长路

    首先tarjan缩点

    然后强连通分量连边

    下面跑拓扑排序,入度为0的强连通分量 first

    然后 dis[ ] 计算到达这个强连通分量时的最大权值(感觉这里有点像最长路QWQ)

    最后取一个最大的 dis[ ]

    拓扑:

    把强连通分量连起来,然后拓扑排序寻找入度为0的点,更新dis[]

    然后枚举出边,更新dis[],最后取最大

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<string>
    #include<cstring>
    #include<cstdlib>
    #include<queue>
    
    using namespace std;
    
    inline int read()
    {
        int ans=0;
        char last=' ',ch=getchar();
        while(ch<'0'||ch>'9') last=ch,ch=getchar();
        while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
        if(last=='-') ans=-ans;
        return ans;
    }
    
    const int maxn=100010;
    int n,m,edge_num=0,qltedge_num=0,tim=0,top=0,qltnum=0;
    int head[maxn],qlthead[maxn],dfn[maxn],vis[maxn],low[maxn],cost[maxn];
    int s[maxn],color[maxn],size[maxn],out[maxn],val[maxn],dis[maxn],in[maxn];
    struct node
    {
        int nxt,to;
    }edge[maxn],qltedge[maxn];
    
    void addedge1(int u,int v)
    {
        edge_num++;
        edge[edge_num].to =v;
        edge[edge_num].nxt =head[u];
        head[u]=edge_num;
    }
    
    void addedge2(int u,int v)
    {
        qltedge_num++;
        qltedge[qltedge_num].to =v;
        qltedge[qltedge_num].nxt =qlthead[u];
        qlthead[u]=qltedge_num;
    }
    
    void tarjan(int x)
    {
        dfn[x]=low[x]=++tim;
        vis[x]=1;
        s[++top]=x;
        for(int i=head[x];i;i=edge[i].nxt )
        {
            int y=edge[i].to ;
            if(!dfn[y])
            {
                tarjan(y);
                low[x]=min(low[x],low[y]);
            }
            else if(vis[y])
                low[x]=min(low[x],dfn[y]);
        }
        if(dfn[x]==low[x])
        {
            qltnum++;
            int y;
            do
            {
                y=s[top--];
                vis[y]=0;
                color[y]=qltnum;
                size[qltnum]++;
                val[qltnum]+=cost[y];
            }while(x!=y);
        }
    }
    
    int topo()
    {
        queue<int> q;
        for(int i=1;i<=qltnum;i++)
        {
            if(!in[i])
            q.push(i);
            dis[i]=val[i]; 
        }
        while(!q.empty()  )
        {
            int x=q.front() ;
            q.pop() ;
            for(int i=qlthead[x];i;i=qltedge[i].nxt )
            {
                int y=qltedge[i].to ;
                if(dis[y]<dis[x]+val[y])
                  dis[y]=dis[x]+val[y];
                in[y]--;
                if(!in[y])
                  q.push(y); 
            }
        }
        
        int ans=0;
        for(int i=1;i<=qltnum;i++)
          ans=max(ans,dis[i]);
        return ans;
        
    }
    
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=n;i++) cost[i]=read();
        int u,v;
        for(int i=1;i<=m;i++)
        {
            u=read();v=read();
            addedge1(u,v);
        }
        for(int i=1;i<=n;i++)
        {
            if(!dfn[i]) tarjan(i);
        }
        
        for(int i=1;i<=n;i++)
           for(int j=head[i];j;j=edge[j].nxt )
           {
               if(color[i]!=color[edge[j].to ])
               {
                   addedge2(color[i],color[edge[j].to ]);
                   in[color[edge[j].to ]]++;
            }    
           }
        
        printf("%d
    ",topo());
        
        return 0;
    }
  • 相关阅读:
    vuex状态管理
    vue3.0创建一个项目
    Django + Vue
    Django部署
    django简单使用
    Django模型
    Centos7编译openjdk8源码
    深入了解final
    深入了解java值传递
    java自带的Logger日志系统
  • 原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11242799.html
Copyright © 2011-2022 走看看