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 }
  • 相关阅读:
    ....
    CodeForces 375A(同余)
    POJ 2377 Bad Cowtractors (最小生成树)
    POJ 1258 AgriNet (最小生成树)
    HDU 1016 Prime Ring Problem(全排列)
    HDU 4460 Friend Chains(bfs)
    POJ 2236 Wireless Network(并查集)
    POJ 2100 Graveyard Design(尺取)
    POJ 2110 Mountain Walking(二分/bfs)
    CodeForces 1059B Forgery(模拟)
  • 原文地址:https://www.cnblogs.com/Missa/p/2908139.html
Copyright © 2011-2022 走看看