• HDU 2767 Proving Equivalences 图论scc缩点


    问一个图,最少需要加多少条边,使得这个图强联通。

    Tarjan缩点,重建图,令a=入度为0的scc个数,b=出度为0的scc个数,ans=max(a,b);

    若图scc=1,本身强联通,ans=0;

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int MAXN = 20010;//点数 
     4 const int MAXM = 200100;//边数 
     5 struct Edge {  
     6     int to,next; 
     7 }edge[MAXM]; 
     8 int head[MAXN],tot,a,b; 
     9 int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];//Belong数组的值是1~scc 
    10 int Index,top; int scc;//强连通分量的个数 
    11 int in[MAXN],out[MAXN];
    12 bool Instack[MAXN]; 
    13 int num[MAXN];//各个强连通分量包含点的个数,数组编号1~scc //num数组不一定需要,结合实际情况 
    14  
    15 void addedge(int u,int v){  
    16     edge[tot].to = v;
    17     edge[tot].next = head[u];
    18     head[u] = tot++; 
    19 } 
    20 void Tarjan(int u){
    21     int v;  
    22     Low[u] = DFN[u] = ++Index; 
    23     Stack[top++] = u;  
    24     Instack[u] = true;  
    25     for(int i = head[u];i != -1;i = edge[i].next) {  
    26         v = edge[i].to;   
    27         if( !DFN[v] ){
    28             Tarjan(v);   
    29             if( Low[u] > Low[v] )
    30                 Low[u] = Low[v];   
    31         }   
    32         else if(Instack[v] && Low[u] > DFN[v])
    33             Low[u] = DFN[v];  
    34         }  
    35         if(Low[u] == DFN[u]){ 
    36             scc++; 
    37             do{    
    38                 v = Stack[--top];
    39                 Instack[v] = false;    
    40                 Belong[v] = scc;    
    41                 num[scc]++;   
    42             }while( v != u);  
    43         } 
    44 } 
    45 void find_degree(int u){
    46     int v;
    47     for(int i = head[u];i != -1;i = edge[i].next){
    48         v = edge[i].to;
    49         if(Belong[u]==Belong[v]) continue;
    50         in[Belong[v]]++;
    51         out[Belong[u]]++;
    52     }
    53 }
    54 void solve(int N){
    55     memset(DFN,0,sizeof(DFN));
    56     memset(Instack,false,sizeof(Instack));
    57     memset(num,0,sizeof(num));  
    58     Index = scc = top = 0;  
    59     for(int i = 1;i <= N;i++)
    60         if(!DFN[i])    
    61         Tarjan(i); 
    62     for(int i=1;i<=N;i++){
    63         find_degree(i);
    64     }
    65     if(scc==1) return;
    66     for(int i=1;i<=scc;i++){
    67         if(in[i]==0) a++;
    68         if(out[i]==0) b++;
    69     }
    70 } 
    71 void init(){
    72     tot = 0; 
    73     a=0,b=0;
    74     memset(head,-1,sizeof(head)); 
    75     memset(in,0,sizeof(in));
    76     memset(out,0,sizeof(out));
    77 } 
    78 int main(){
    79     int n,m,u,v,T;
    80     cin>>T;
    81     while(T--){
    82         scanf("%d%d",&n,&m); 
    83         init();
    84         for(int i=1;i<=m;i++){
    85             scanf("%d%d",&u,&v);
    86             addedge(u,v);
    87         }
    88         solve(n);
    89         cout<<max(a,b)<<endl;
    90     }
    91     return 0;
    92 }
  • 相关阅读:
    Flex 布局
    前端跨域之jsonp
    vs code 自定义代码片段
    vue中使用axios进行http通信
    Table边框合并
    getElementsBy 系列方法相比querySelector系列的区别
    vue中watch简单使用
    png图标任意赋色
    pc端与移动端适配解决方案之rem
    Express post请求无法解析参数的原因
  • 原文地址:https://www.cnblogs.com/poler/p/7389070.html
Copyright © 2020-2023  润新知