• POJ 1236 Tarjan缩点+求度数


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

    题目大意:

      给定一个n (n<=100)个点的有向图,问:
      Q1、最少需要选择多少个点,使得从这些点出发能遍历完整个图;
      Q2、最少需要添加多少条有向边,使得整个图成为连通图;

    分析:

            开始Q1我想复杂了,先说Q2吧,和hdu2767一样,当时我自己ac了hdu2767,可是做Q2的时候又一下没想到,便找出了原来的代码……

            先由Tarjan算法求出强连通分量后进行缩点,得到每个强连通分量的入度in[],出度out[];

      Q1: 入度为0的强连通分量个数;  

      Q2: max(  入度为0的强连通分量个数 ,  出度为0的强连通分量个数  );

    代码:

    poj1236
      1 /*1236    Accepted    264K    32MS    C++    2408B    2012-04-17 12:29:23*/
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <iostream>
      6 #include <algorithm>
      7 #include <vector>
      8 using namespace std;
      9 
     10 #define mpair make_pair
     11 #define pii pair<int,int>
     12 #define MM(a,b) memset(a,b,sizeof(a));
     13 typedef long long lld;
     14 typedef unsigned long long u64;
     15 template<class T> bool up_max(T& a,const T& b){return b>a? a=b,1 : 0;}
     16 template<class T> bool up_min(T& a,const T& b){return b<a? a=b,1 : 0;}
     17 #define maxn 110
     18 
     19 int n;
     20 vector<int> adj[maxn];
     21 
     22 bool vis[maxn];
     23 int Bcnt, Top, Index;
     24 int stack[maxn], low[maxn], dfn[maxn];
     25 int belong[maxn];
     26 void Init_tarjan(){
     27     Bcnt= Top= Index= 0;
     28     for(int i=1;i<=n;++i) low[i]= dfn[i]= vis[i]= 0;
     29 }
     30 void Tarjan(int u){
     31     vis[u]= 1; /// push() into stack;
     32     stack[++Top]= u;
     33     low[u]= dfn[u]= ++Index;
     34     for(int i=0;i<adj[u].size();++i){
     35         int v= adj[u][i];
     36         if( !dfn[v] ){
     37             Tarjan( v );
     38             up_min( low[u], low[v] );
     39         }
     40         else if( vis[v] )
     41             up_min( low[u], dfn[v] );
     42     }
     43     if( low[u]==dfn[u] ){
     44         ++Bcnt;
     45         int v;
     46         do{
     47             v= stack[Top--];
     48             belong[v]= Bcnt;
     49             vis[v]= 0; /// pop() from stack;
     50         }while( u!=v );
     51     }
     52 }
     53 
     54 int in[maxn], out[maxn];
     55 void dfs(int u){;
     56     vis[u]= 1;
     57     for(int i=0;i<adj[u].size();++i){
     58         int v= adj[u][i];
     59         if( belong[u] !=belong[v] ){
     60             out[ belong[u] ]++;
     61             in[ belong[v] ]++;
     62         }
     63         if( !vis[v] )
     64             dfs( v );
     65     }
     66 }
     67 
     68 int main()
     69 {
     70     //freopen("1236.in","r",stdin);
     71     int i,t;
     72     while(cin>>n){
     73         for(i=1;i<=n;++i) adj[i].clear();
     74         for(i=1;i<=n;++i){
     75             while( scanf("%d", &t), t )
     76                 adj[i].push_back( t );
     77         }
     78 
     79         Init_tarjan();
     80         for(i=1;i<=n;++i)
     81             if( !dfn[i] ){ /// dfn[i]!!!
     82                 Tarjan(i);
     83             }
     84 
     85         if( 1==Bcnt ){ ///
     86             puts("1\n0");
     87             continue;
     88         }
     89 
     90         for(i=1;i<=Bcnt;++i) in[i]= out[i]= 0;
     91         fill( vis+1, vis+1+n, 0 );
     92         for(i=1;i<=n;++i){
     93             if( !vis[i] )
     94                 dfs(i);
     95         }
     96 
     97         int s1=0, s2=0;
     98         for(i=1;i<=Bcnt;++i){
     99             if( 0==in[i] ) s1++;
    100             if( 0==out[i] ) s2++;
    101         }
    102         printf("%d\n%d\n", s1, max(s1,s2) );
    103     }
    104 }
    一毛原创作品,转载请注明出处。
  • 相关阅读:
    本周总结
    本周总结:用户故事和用户场景
    排球比赛规则说明书
    我与计算机
    官网地址备份
    连续自然数序列,求取中位数方案
    Spark 实现自定义对象sequenceFile方式存储,读写示例(scala编写)
    hbase 异常
    python_初步
    redis_入门网址
  • 原文地址:https://www.cnblogs.com/yimao/p/2453473.html
Copyright © 2020-2023  润新知