zoukankan      html  css  js  c++  java
  • poj1236 有向图加边变成强连通图

    给我们一个有向图,有两个问题

    1、最少要给多少个点发消息,才能使得所有的点都收到消息(消息可以随边传递)

    2、最少需要多少条边才能使得图变成强连通图

    对于一个强连通分量,可以当做一个点来考虑,所以我们可以缩点,然后得到DAG图,

    那么对于第一个问,即是入度为0的点有多少个,因为入度为0的点无法收到消息。

    对于第二问,只要加max(s1,s2)条边,就能使得DAG变成强连通图,  s1表示入度为0的点的个数,s2表示出度为0的点的个数

    设s1 > s2, 那么首先加s2条边,这s2条边连接的是入度为0和出度为0的点,

    然后剩下s1-s2个入度为0的点, 那么随便加s1-s2条边即可。

      1 #pragma warning(disable:4996)
      2 #pragma comment(linker, "/STACK:1024000000,1024000000")
      3 #include <stdio.h>
      4 #include <string.h>
      5 #include <time.h>
      6 #include <math.h>
      7 #include <map>
      8 #include <set>
      9 #include <queue>
     10 #include <stack>
     11 #include <vector>
     12 #include <bitset>
     13 #include <algorithm>
     14 #include <iostream>
     15 #include <string>
     16 #include <functional>
     17 #include <iostream>
     18 typedef __int64 LL;
     19 const int INF = 1 << 30;
     20 using namespace std;
     21 /*
     22 考虑如果是的一个有向图,变成连通图,
     23 将强联通分量缩成一个点,
     24 然后,如果某一个联通分量和其他的联通分量没有边,那么要加两条边,如果只有一条边
     25 那么只要加1条边
     26 */
     27 const int N = 100 + 10;
     28 int dfn[N], low[N], sccno[N], dfs_clock, cnt;
     29 stack<int> st;
     30 vector<int> g[N];
     31 
     32 void tarjan(int u, int fa)
     33 {
     34     dfn[u] = low[u] = ++dfs_clock;
     35     st.push(u);
     36     for (int i = 0; i<g[u].size(); ++i)
     37     {
     38         int v = g[u][i];
     39         if (dfn[v] == 0)
     40         {
     41             tarjan(v, u);
     42             low[u] = min(low[u], low[v]);
     43         }
     44         else if (sccno[v] == 0)//因为有向图存在横插边,不能用横插边来更新low[u]
     45         {
     46             low[u] = min(low[u], low[v]);
     47         }
     48     }
     49     //同样,因为强连通分量可以分布在根结点的两个分支上,所以在递归返回的时候调用
     50     if (low[u] == dfn[u])
     51     {
     52         cnt++;
     53         for (;;)
     54         {
     55             int x = st.top();
     56             st.pop();
     57             sccno[x] = cnt;
     58             if (x == u)
     59                 break;
     60         }
     61     }
     62 }
     63 bool in[N], out[N];
     64 int main()
     65 {    
     66     
     67     int n;
     68     while (scanf("%d", &n) != EOF)
     69     {
     70         dfs_clock = cnt = 0;
     71         while (!st.empty()) st.pop();
     72         for (int i = 1;i <= n;++i)
     73         {
     74             sccno[i] = 0;
     75             g[i].clear();
     76             low[i] = dfn[i] = 0;
     77             in[i] = out[i] = false;
     78         }
     79         for (int i = 1;i <= n;++i)
     80         {
     81             int u = i, v;
     82             while (scanf("%d", &v), v)
     83                 g[u].push_back(v);
     84         }
     85         for (int i = 1;i <= n;++i)
     86         {
     87             if (dfn[i] == 0)
     88                 tarjan(i, -1);
     89         }
     90         for (int i = 1;i <= n;++i)
     91         {
     92             for (int j = 0;j < g[i].size();++j)
     93             {
     94                 int v = g[i][j];
     95                 if (sccno[i] == sccno[v]) continue;
     96                 out[sccno[i]] = true;
     97                 in[sccno[v]] = true;
     98             }
     99         }
    100         if (cnt == 1)
    101         {
    102             printf("1
    0
    ");
    103             continue;
    104         }
    105         int cnt1 = 0, cnt2 = 0;
    106         for (int i = 1;i <= cnt;++i)
    107         {
    108             if (!in[i]) cnt1++;
    109             if (!out[i]) cnt2++;
    110         }
    111         printf("%d
    ", cnt1);
    112         printf("%d
    ", max(cnt1, cnt2));
    113     }
    114     return 0;
    115 }
  • 相关阅读:
    第04组 beta冲刺(1/4)
    2019 SDN上机第5次作业
    SDN课程阅读作业(2)
    第04组 Alpha事后诸葛亮
    C Primer 复习题
    C Primer 编程练习
    C语言I博客作业04
    C语言I博客作业03
    C语言I博客作业02
    Appium + java截图方法
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4794810.html
Copyright © 2011-2022 走看看