• LA 4287 有相图的强连通分量


     大白书P322 , 一个有向图在添加至少的边使得整个图变成强连通图, 是计算整个图有a个点没有 入度, b 个点没有出度, 答案为 max(a,b) ; 至今不知所云。(求教)

    #include <iostream>
    #include <vector>
    #include <stack>
    #include <cstdio>
    #include <string.h>
    using namespace std;
    const int maxn = 20000+10;
    vector<int> G[maxn];
    int pre[maxn], lowlink[maxn],sccno[maxn],dfs_clock, scc_cnt;
    stack<int>S;
    void dfs(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]){
                   dfs(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++;
             for(;;){
                 int x =S.top(); S.pop();
                 sccno[x] =scc_cnt;
                 if(x==u) break;
             }
         }
    }
    void find_scc(int n){
         dfs_clock = scc_cnt =0;
         memset(sccno,0,sizeof(sccno));
         memset(pre,0,sizeof(pre));
         for(int i=0; i<n; i++)
            if(!pre[i]) dfs(i);
    }
    int in0[maxn],out0[maxn];
    
    int main()
    {
         int T,n,m;
         scanf("%d",&T);
         while(T--){
            scanf("%d%d",&n,&m);
             for(int i=0; i<n; i++)G[i].clear();
             for(int i=0; i<m ; i++){
                  int u,v;
                  scanf("%d%d",&u,&v); u--;v--;
                    G[u].push_back(v);
             }
             find_scc(n);
             for(int i=1; i<=scc_cnt; ++i ) in0[i] = out0[i] =1;
             for(int u=0; u<n; u++)
             for(int i=0; i<G[u].size(); i++){
                int v = G[u][i];
                if(sccno[u] != sccno[v] ) in0[sccno[v]]=out0[sccno[u]] =0;
             }
             int a=0, b=0;
             for(int i=1; i<=scc_cnt; i++){
                  if(in0[i]) a++;
                  if(out0[i]) b++;
             }
             int ans= max(a,b);
             if(scc_cnt ==1 ) ans=0;
             printf("%d
    ",ans);
         }
        return 0;
    }
    View Code
  • 相关阅读:
    ros 录制
    shell 截取字符串
    Linux 关机
    shell获取字符串长度
    ubuntu14.04 设置开机自启动脚本
    获取本机ip的shell脚本
    shell 杀掉指定进程的服务
    html 绘制矩形轨迹,选中区域
    shell模拟ctrl c停止
    shell 字符串提取数字
  • 原文地址:https://www.cnblogs.com/Opaser/p/4314088.html
Copyright © 2020-2023  润新知