zoukankan      html  css  js  c++  java
  • LA4287图论+ 有向图SCC+缩点

     1 /*
     2 LA4287图论
     3 有向图SCC
     4 关键点:
     5 1、事件抽象成图的节点
     6 2、建立相似的模型(有向图SCC)
     7 3、等效代替:缩点的思想
     8 4、图论知识:非强连通转强连通

         补充:a个缩点入度为0b个出度为0,则添加max(a,b)条有向边,可以成为有向图的强连通分量

     9 */
    10 #include <stdio.h>
    11 #include <stdlib.h>
    12 #include <string.h>
    13 #include <math.h>
    14 #include <ctype.h>
    15 #include <string>
    16 #include <iostream>
    17 #include <sstream>
    18 #include <vector>
    19 #include <queue>
    20 #include <stack>
    21 #include <map>
    22 #include <list>
    23 #include <set>
    24 #include <algorithm>
    25 #define maxn 20100
    26 using namespace std;
    27 
    28 int pre[maxn] , low[maxn] , sccno[maxn] , dfs_clock , scc_cnt;
    29 vector<int>G[maxn];
    30 stack<int>S;
    31 
    32 void dfs(int u){
    33     pre[u] = low[u] = ++dfs_clock;
    34     S.push(u);
    35     int ecnt = G[u].size();
    36     for(int i=0;i<ecnt;i++){
    37         int v = G[u][i];
    38         if(!pre[v]){
    39             dfs(v);
    40             low[u] = min(low[u] , low[v]);
    41         }
    42         else if(!sccno[v]){
    43             low[u] = min(low[u] , pre[v]);
    44         }
    45     }
    46     if(low[u] == pre[u]){
    47         scc_cnt++;
    48         for(;;){
    49             int x = S.top() ; S.pop();
    50             sccno[x] = scc_cnt;
    51             if(x==u) break;
    52         }
    53     }
    54 }
    55 void find_scc(int n){
    56     dfs_clock = scc_cnt = 0;
    57     memset(pre, 0 ,sizeof(pre));
    58     memset(sccno , 0, sizeof(sccno));
    59     for(int i=1;i<=n; i++){
    60         if(!pre[i]) dfs(i);
    61     }
    62 }
    63 int solve(int n)
    64 {
    65     find_scc(n);
    66     bool ind[maxn],oud[maxn];//缩点后的顶点的入度,出度是否大于0
    67     memset(ind,0,sizeof(ind));
    68     memset(oud,0,sizeof(oud));
    69     for(int i=1;i<=n;i++){//枚举每条边
    70     for(int j=0;j<G[i].size();j++){
    71     int u=i,v=G[i][j];
    72     if(sccno[u]!=sccno[v]) oud[sccno[u]]=ind[sccno[v]]=true;
    73     }
    74     }
    75     int a=0,b=0;
    76     for(int i=1;i<=scc_cnt;i++){
    77     if(!ind[i]) a++;
    78     if(!oud[i]) b++;
    79     }
    80     if (scc_cnt==1) return 0;else return max(a,b);
    81     //ps,scc_cnt==1时错误产生原因:上面的方法是运用必要条件来判断,破坏入度/出度为0的唯一情况,但是如果只有一个连通块,初始值就出现问题了
    82 }
    83 int main()
    84 {
    85     int n,m;
    86     int t;cin>>t;
    87     while(t--){
    88         cin>>n>>m;
    89         for(int i=1;i<=n;i++) G[i].clear();
    90         for(int i=1;i<=m;i++){
    91         int u,v;
    92         cin>>u>>v;
    93         G[u].push_back(v);
    94         }
    95         cout<<solve(n)<<endl;
    96     }
    97     return 0;
    98 }
  • 相关阅读:
    Mybatis-plus学习笔记(一)
    Mysql基础(四)分组查询及连接查询
    Mysql 基础(三)排序查询及常用函数
    CyclicBarrier 使用详解
    countDownLatch
    pom所有依赖version红色但是不影响运行
    iText5实现Java生成PDF文件完整版
    【Maven】---Nexus私服配置Setting和Pom
    引用、指针、const、define、static、sizeof、左值右值
    事物隔离级别、MVCC以及数据库中常见锁介绍
  • 原文地址:https://www.cnblogs.com/little-w/p/3570217.html
Copyright © 2011-2022 走看看