• 构造强连通图


      

      我们知道,要把一个非边双连通图构造成一个边双连通图,只需把这个图化简(边双连通分量缩点)成一个树,然后 找出叶子节点个数leaf,(leaf+1)/2就是要新添加的边数。

      现在,对与有向图来说,我们需要求加最少的边,使得一个非强连通图变成一个强连通图,最少的边数是多少?

      同样的,我们需要把他化简(强连通分量缩点)成一个DAG图(有向无环图),然后找出入度为0的顶点个数in,和出度为0的顶点个数out,取他们的最大值就是需要添加的最少的边数。

      对于一种特殊情况,若原图中本身就是一个强连通图,那么缩点后的DGA图就是一个孤立的点,in和out分别等于1,按上述方式求的答案为1,显然和正确答案0不同,所以,我们在此特判一下即可。

      poj 1236

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <queue>
      4 #include <algorithm>
      5 #define _Clr(x, y) memset(x, y, sizeof(x))
      6 #define INF 0x3f3f3f3f
      7 #define N 110
      8 using namespace std;
      9 
     10 struct Node
     11 {
     12     int to, next;
     13 }edge[N*100];
     14 int head[N], tot;
     15 int dfn[N], low[N];
     16 int Sta[N], bleg[N];
     17 bool instack[N];
     18 int n, cnt, top, ght;
     19 
     20 void Init()
     21 {
     22     cnt=tot=top=ght=0;
     23     _Clr(head, -1);
     24     _Clr(dfn, 0);
     25     _Clr(instack, 0);
     26 }
     27 
     28 void Add_edge(int a, int b)
     29 {
     30     edge[tot].to = b;
     31     edge[tot].next = head[a];
     32     head[a] = tot++;
     33 }
     34 
     35 void dfs(int u)
     36 {
     37     dfn[u]=low[u]=++cnt;
     38     instack[u] = true;
     39     Sta[top++] = u;
     40     for(int i=head[u]; i!=-1; i=edge[i].next)
     41     {
     42         int v = edge[i].to;
     43         if(!dfn[v])
     44         {
     45             dfs(v);
     46             low[u] = min(low[u], low[v]);
     47         }
     48         else if(instack[v]) low[u] = min(low[u], dfn[v]);
     49     }
     50     if(low[u]==dfn[u])
     51     {
     52         ght++;
     53   //      printf("Num:%d
    ",ght);
     54         int v;
     55         do
     56         {
     57             v = Sta[--top];
     58     //        printf("%d ", v);
     59             instack[v] = false;
     60             bleg[v] = ght;
     61         }while(u != v);
     62       //  puts("");
     63     }
     64 }
     65 
     66 int inde[N], outde[N];
     67 void Tarjan()
     68 {
     69     for(int i=1; i<=n; i++)
     70         if(!dfn[i]) dfs(i);
     71 
     72     _Clr(inde, 0);
     73     _Clr(outde, 0);
     74     for(int u=1; u<=n; u++)
     75     for(int i=head[u];  i!=-1; i=edge[i].next)
     76     {
     77         int v = edge[i].to;
     78         if(bleg[v] != bleg[u])
     79             inde[bleg[v]]++, outde[bleg[u]]++;
     80     }
     81 }
     82 
     83 void Solved()
     84 {
     85     int a=0, b=0;
     86     if(ght==1)
     87         printf("1
    0
    ");
     88     else
     89     {
     90         for(int i=1; i<=ght; i++)
     91         {
     92             if(inde[i]==0) a++;
     93             if(outde[i]==0) b++;
     94         }
     95         printf("%d
    %d
    ", a, max(a, b));
     96     }
     97 }
     98 int main()
     99 {
    100     int b;
    101     while(~scanf("%d", &n))
    102     {
    103         Init();
    104         for(int i=1; i<=n; i++)
    105         {
    106             while(scanf("%d", &b) && b)
    107                 Add_edge(i, b);
    108         }
    109         Tarjan();
    110         Solved();
    111     }
    112     return 0;
    113 }
    View Code
  • 相关阅读:
    struct resbuf 结构就象LISP里面的表(
    CString互转int
    C++中std::sort/std::stable_sort/std::partial_sort的区别及使用
    *ARX对数据的类型和单位进行转换
    c++常见容器操作
    C++中const关键字的使用方法,烦透了一遍一遍的搜,总结一下,加深印象!!!
    ARX 简单程序(不错的例子)
    ARX对象的一些文字说明
    CAD ObjectARX扩展工具的源码(一)
    CAD ObjectARX扩展工具的源码(三)
  • 原文地址:https://www.cnblogs.com/khan724/p/4374379.html
Copyright © 2020-2023  润新知