zoukankan      html  css  js  c++  java
  • poj 1236(强连通分量)

    题目大意:   给定一个n (n<=100)个点的有向图,

    问:Q1、最少需要选择多少个点,使得从这些点出发能遍历完整个图; 

      Q2、最少需要添加多少条有向边,使得整个图成为强连通图; 

      分析: 

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

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

      注意的地方:假如原图就是一个强连通图。则显然Q2是0.

    kosaraju:

    View Code
      1 // File Name: 1236.cpp
      2 // Author: Missa
      3 // Created Time: 2013/2/6 星期三 19:44:12
      4 
      5 #include<iostream>
      6 #include<cstdio>
      7 #include<cstring>
      8 #include<algorithm>
      9 #include<cmath>
     10 #include<queue>
     11 #include<stack>
     12 #include<string>
     13 #include<vector>
     14 #include<cstdlib>
     15 #include<map>
     16 using namespace std;
     17 
     18 const int maxn = 1e2+5;
     19 int n;
     20 vector<int>adj[maxn];
     21 vector<int>radj[maxn];
     22 vector<int>ord;
     23 bool vis[maxn];
     24 int ma[maxn];
     25 int cnt;
     26 void init()
     27 {
     28     for(int i=0;i<maxn;i++)
     29     {
     30         adj[i].clear();
     31         radj[i].clear();
     32     }
     33     ord.clear();
     34     cnt=0;
     35 }
     36 void dfs1(int v)
     37 {
     38     vis[v]=1;
     39     for(int i=0;i<adj[v].size();i++)
     40         if(!vis[adj[v][i]])
     41             dfs1(adj[v][i]);
     42     ord.push_back(v);
     43 }
     44 void dfs2(int v)
     45 {
     46     vis[v]=1;
     47     ma[v]=cnt;
     48     for(int i=0;i<radj[v].size();i++)
     49         if(!vis[radj[v][i]])
     50             dfs2(radj[v][i]);
     51 }
     52 void kosaraju()
     53 {
     54     memset(vis,0,sizeof(vis));
     55     ord.clear();
     56     for(int i=1;i<=n;i++)
     57         if(!vis[i])
     58             dfs1(i);
     59     memset(vis,0,sizeof(vis));
     60     cnt=0;
     61     for(int i=ord.size()-1;i>=0;i--)
     62     {
     63         if(!vis[ord[i]])
     64         {
     65             cnt++;
     66             dfs2(ord[i]);
     67         }
     68     }
     69 }
     70 void read()
     71 {
     72     for(int i=1;i<=n;i++)
     73     {
     74         int x;
     75         while(scanf("%d",&x))
     76         {
     77             if(x==0) break;
     78             adj[i].push_back(x);
     79             radj[x].push_back(i);
     80         }
     81     }
     82 }
     83 void solve()
     84 {
     85     int ans1=0,ans2=0;
     86     int in[maxn],out[maxn];//入度,出度
     87     memset(in,0,sizeof(in));
     88     memset(out,0,sizeof(out));
     89     for(int i=1;i<=n;i++)
     90     {
     91         for(int j=0;j<adj[i].size();j++)
     92         {
     93             int tt=adj[i][j];
     94             if(ma[i]==ma[tt]) continue;
     95             out[ma[i]]++;
     96             in[ma[tt]]++;
     97         }
     98     }
     99     for(int i=1;i<=cnt;i++)
    100     {
    101         if(in[i]==0) ans1++;
    102         if(out[i]==0) ans2++;
    103     }
    104     printf("%d\n",ans1);
    105     if(cnt==1)//原图是一个强连通分量
    106         printf("0\n");
    107     else
    108         printf("%d\n",max(ans1,ans2));
    109 }
    110 int main()
    111 {
    112     while(~scanf("%d",&n))
    113     {
    114         init();
    115         read();
    116         kosaraju();
    117         solve();
    118     }
    119     return 0;
    120 }
  • 相关阅读:
    bzoj 1030 [JSOI2007]文本生成器
    Swift 学习笔记 (闭包)
    Swift 学习笔记 (函数)
    HTML 学习笔记 JQueryUI(Interactions,Widgets)
    HTML 学习笔记 JQuery(表单,表格 操作)
    HTML 学习笔记 JQuery(animation)
    HTML 学习笔记 JQuery(盒子操作)
    HTML 学习笔记 JQuery(事件)
    HTML 学习笔记 JQuery(DOM 操作3)
    HTML 学习笔记 JQuery(DOM 操作2)
  • 原文地址:https://www.cnblogs.com/Missa/p/2908139.html
Copyright © 2011-2022 走看看