zoukankan      html  css  js  c++  java
  • poj 1236强连通图缩点

    题目链接:http://poj.org/problem?id=1236

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <queue>
    #include <vector>
    
    #define maxn 105
    #define INF  0x3f3f3f
    using namespace std;
    
    bool G1[maxn][maxn],G2[maxn][maxn];
    vector<int> s;
    int vis[maxn],sccnum[maxn],scc_cnt;
    int N;
    int in[maxn],out[maxn];
    
    /* 
    void dfs(int u){
        vis[u] = true;
        for(int i=1;i<=N;i++){
            if(!vis[i]){
                dfs(i);
            }
        }
    }*/
    void dfs1(int u){
        if(vis[u])  return;
        vis[u] = 1;
        for(int i=1;i<=N;i++){
            if(G1[u][i]){
                dfs1(i); 
            }
        }    //printf("u %d
    ",u); 
        s.push_back(u);
    }
    void dfs2(int u){
        if(sccnum[u])  return;
        sccnum[u] = scc_cnt;  //printf("***  %d  %d
    ",u,scc_cnt);
        for(int i=1;i<=N;i++)
           if(G2[u][i]) { //printf("i  %d
    ",i);
                  dfs2(i);
           } 
    }
    void Get_new_graph(){
        memset(in,0,sizeof(in));
        memset(out,0,sizeof(out));
        for(int i=1;i<=N;i++)
          for(int j=1;j<=N;j++){
              if(sccnum[i] != sccnum[j] && G1[i][j]){
                  in[sccnum[j]]++;
                  out[sccnum[i]]++;
            }
          }
    }
    void find_scc(){
        scc_cnt = 0;
        s.clear();
        memset(sccnum,0,sizeof(sccnum));
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=N;i++) dfs1(i); 
        for(int i=N-1;i>=0;i--){  //还不能理解这个关于dfs 
            if(!sccnum[s[i]]){
                scc_cnt++;  //printf("s[i]   %d
    ",s[i]);
                dfs2(s[i]);
            } 
        }
        Get_new_graph();
    }
    int main()
    {
        freopen("input.txt","r",stdin);
        scanf("%d",&N);
        memset(G1,0,sizeof(G1));
        memset(G2,0,sizeof(G2));
        for(int i=1;i<=N;i++){
            int a;
            while(scanf("%d",&a) && a){
                G1[i][a] = true;
                G2[a][i] = true;
            }
        }
        /*  
        int bcc_cnt = 0;
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=N;i++){
            if(!vis[i]){
                bcc_cnt++;
                dfs(i);
            }
        }*/   //本题只有一个联通分量; 
        find_scc();
        int ansb = 0;
        int innum = 0,outnum = 0;
        for(int i=1;i<=scc_cnt;i++){
            if(in[i] == 0)  innum++;
            if(out[i] == 0) outnum++;
        }   
        if(scc_cnt == 1) printf("1
    0
    ");  //这个地方就是WA的原因。 
        else{
            printf("%d
    ",innum);
            printf("%d
    ",max(innum,outnum));
        }
    } 
    View Code
  • 相关阅读:
    PHP设计模式
    秒杀方案
    lua 安装
    docker 相关命令
    dockerfile
    JS工具对象 DATE 方法
    JS工具对象 Array
    JS工具对象 String 10种常用 方法
    工具对象
    JS工具对象Math 7个常用 方法
  • 原文地址:https://www.cnblogs.com/acmdeweilai/p/3231628.html
Copyright © 2011-2022 走看看