zoukankan      html  css  js  c++  java
  • CDOJ 图论专题 A.不是图论 强连通分量+拓扑排序 经典

    题目链接  在其中纠错第一次wa代码

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <map>
    #include <algorithm>
    #include <set>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long Ull;
    #define MM(a,b) memset(a,b,sizeof(a));
    const double eps = 1e-10;
    const int  inf =0x7f7f7f7f;
    const double pi=acos(-1);
    const int maxn=40000;
    
    vector<int> G[maxn+10],GG[maxn+10];
    int n,m,vlue[maxn+10],pre[maxn+10],deg[maxn],dfs_clock,scc_cnt,sccno[maxn+10],lowlink[maxn+10];
    stack<int> S;
    ll ori[maxn+10],dp[maxn+10];
    ll maxx(ll a,ll b)
    {
        return a>b?a:b;
    }
    void tarjan(int u)
    {
        pre[u]=lowlink[u]=++dfs_clock;
        S.push(u);
        for(int i=0;i<G[u].size();i++)
        {
            int v=G[u][i];
            if(!pre[v])
                {
                    tarjan(v);
                    lowlink[u]=min(lowlink[u],lowlink[v]);
                }
            else if(!sccno[v])
                    lowlink[u]=min(lowlink[u],pre[v]);
        }
    
        if(lowlink[u]==pre[u])
        {
            scc_cnt++;
            while(1)
            {
                int x=S.top();S.pop();
                sccno[x]=scc_cnt;
                if(x==u) break;
            }
        }
    }
    
    void find_scc()
    {
        MM(pre,0);
        MM(sccno,0);
        scc_cnt=dfs_clock=0;
        for(int i=1;i<=n;i++)
          if(!pre[i])
            tarjan(i);
    }
    set<int> st[maxn];
    int main()
    {
        while(~scanf("%d %d",&n,&m))
        {
            for(int i=1;i<=n;i++)
                {
                    st[i].clear();
                    G[i].clear();
                    scanf("%d",&vlue[i]);
                }
    
            for(int i=1;i<=m;i++)
                {
                  int u,v;
                  scanf("%d %d",&u,&v);
                  G[u].push_back(v);
                }
    
            find_scc();
    
            for(int i=1;i<=scc_cnt;i++) {
                    deg[i]=dp[i]=ori[i]=0;
                    GG[i].clear();
            }
            for(int i=1;i<=n;i++)
                 ori[sccno[i]]+=vlue[i];
            if(scc_cnt==1) {printf("%lld
    ",ori[1]);continue;}//需要特判,因为ans初始化为0或者
                                                          //不特判但将ans初始化为dp[1]
            for(int i=1;i<=n;i++)
              for(int j=0;j<G[i].size();j++)
                 if(sccno[i]!=sccno[G[i][j]])
                {
                   int u=sccno[i],v=sccno[G[i][j]];
                   if(!st[u].count(v))//set判断图的连通性
                    {
                        GG[u].push_back(v);
                        st[u].insert(v);
                        deg[v]++;
                    }
                }
    
            ll ans=0;
            for(int i=1;i<=scc_cnt;i++) dp[i]=ori[i];
    
            queue<int> q;//拓扑排序是需要借助BFS的
            for(int i=1;i<=scc_cnt;i++)
                 if(!deg[i]) q.push(i);
    
            while(q.size())
            {
                int u=q.front();q.pop();
                for(int i=0;i<GG[u].size();i++)
                {
                    int v=GG[u][i];
                    dp[v]=maxx(dp[v],dp[u]+ori[v]);
                    ans=maxx(ans,dp[v]);
                    deg[v]--;
                    if(!deg[v]) q.push(v);
                }
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }

     第一次wa代码:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <map>
    #include <algorithm>
    #include <set>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long Ull;
    #define MM(a,b) memset(a,b,sizeof(a));
    const double eps = 1e-10;
    const int  inf =0x7f7f7f7f;
    const double pi=acos(-1);
    const int maxn=40000;
    
    vector<int> G[maxn+10],GG[maxn+10];
    int n,m,vlue[maxn+10],ori[maxn+10],dp[maxn+10],pre[maxn+10],dfs_clock,scc_cnt,sccno[maxn+10],lowlink[maxn+10];
    stack<int> S;
    
    void tarjan(int u)
    {
        pre[u]=lowlink[u]=++dfs_clock;
        S.push(u);
        for(int i=0;i<G[u].size();i++)
        {
            int v=G[u][i];
            if(!pre[v])
                {
                    tarjan(v);
                    lowlink[u]=min(lowlink[u],lowlink[v]);
                }
            else if(!sccno[v])
                    lowlink[u]=min(lowlink[u],pre[v]);
        }
    
        if(lowlink[u]==pre[u])
        {
            scc_cnt++;
            while(1)
            {
                int x=S.top();S.pop();
                sccno[x]=scc_cnt;
                if(x==u) break;
            }
        }
    }
    
    void find_scc()
    {
        MM(pre,0);
        MM(sccno,0);
        scc_cnt=dfs_clock=0;
        for(int i=1;i<=n;i++)
          if(!pre[i])
            tarjan(i);
    }
    
    int main()
    {
        while(~scanf("%d %d",&n,&m))
        {
            for(int i=1;i<=n;i++)
                {
                    G[i].clear();
                    GG[i].clear();
                    scanf("%d",&vlue[i]);
                }
    
            for(int i=1;i<=m;i++)
                {
                  int u,v;
                  scanf("%d %d",&u,&v);
                  G[u].push_back(v);
                }
    
            find_scc();
    
            for(int i=1;i<=scc_cnt;i++) dp[i]=ori[i]=0;
            for(int i=1;i<=n;i++)
                 ori[sccno[i]]+=vlue[i];
    
            for(int i=1;i<=n;i++)
              for(int j=0;j<G[i].size();j++)
                 if(sccno[i]!=sccno[G[i][j]])
                {
                   int u=sccno[i],v=sccno[G[i][j]];
                   if(lower_bound(GG[u].begin(),GG[u].end(),v)==GG[u].end())
                    GG[u].push_back(v);
                }
            int ans=0;
            for(int i=1;i<=scc_cnt;i++) dp[i]=ori[i];
            for(int i=1;i<=scc_cnt;i++)
                for(int j=0;j<GG[i].size();j++)
                {
                 int v=GG[i][j];
                 //printf("1::%d %d %d
    ",i,v,ori[i],ori[v]);
                 dp[v]=max(dp[v],dp[i]+ori[v]);
                 ans=max(ans,dp[v]);
                }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    python之路-HTML初识
    python之路-CentOS6.5 安装Python 的依赖包
    python之路-离线pip下载Python包
    python之路-Memcache
    python之路-SQLAlchemy
    python之路-Redis
    python之路-Mysql
    偶然发现了获取有ID的dom的一种方法
    js 工厂模式和构造函数的区别
    ES6:export和import
  • 原文地址:https://www.cnblogs.com/smilesundream/p/5578190.html
Copyright © 2011-2022 走看看