• hdu 3836 tarjain 求强连通分量个数


      1 //  给你一个有向图,问你最少加几条边能使得该图强连通
      2 #include <iostream>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <string>
      6 #include <utility>
      7 #include <algorithm>
      8 #include <vector>
      9 #include <queue>
     10 #include <stack>
     11 using namespace std;
     12 #define max(x,y) x>=y?x:y
     13 #define lowbit(x) x&(-x)
     14 typedef  long long ll;
     15 const int  N=20010;
     16 int n,m;
     17 int head[N],low[N],num[N];
     18 int  in[N],out[N],be[N];
     19 int  ans,cnt,ans1,ans2;
     20 int  index;
     21 bool vis[N];
     22 struct Edge
     23 {
     24     int from,to,nex;
     25 }e[N*6];
     26 stack<int>s;
     27 void init()
     28 {
     29     memset(head,-1,sizeof(head));
     30     memset(num,-1,sizeof(num));
     31     memset(vis,0,sizeof(vis));
     32     memset(low,0,sizeof(low));
     33     memset(in,0,sizeof(in));
     34     memset(out,0,sizeof(out));
     35     cnt=index=0;    
     36 }
     37 void add(int u,int v)
     38 {
     39     e[cnt].from=u;
     40     e[cnt].to=v;
     41     e[cnt].nex=head[u];
     42     head[u]=cnt++;
     43 }
     44 void tarjan(int u)
     45 {
     46     low[u]=num[u]=++index;
     47     vis[u]=1;
     48     s.push(u);
     49     for (int i=head[u];i!=-1;i=e[i].nex)
     50     {
     51         int v=e[i].to;
     52         if(num[v]==-1)
     53         {
     54             tarjan(v);
     55             low[u]=min(low[u],low[v]);
     56         }
     57         else if(vis[v])
     58         {
     59             low[u]=min(low[u],num[v]);
     60         }
     61     }
     62     if(num[u]==low[u])
     63     {
     64         int x;
     65         ans++;
     66         do{
     67             x=s.top();
     68             s.pop();
     69             vis[x]=0;
     70             be[x]=ans;
     71         }while(x!=u);
     72     }
     73 }
     74 int main()
     75 {
     76     while(~scanf("%d %d",&n,&m))
     77     {
     78         init();
     79         ans=0;
     80         int a,b;
     81         for (int i=0;i<m;i++)
     82         {
     83             scanf("%d %d",&a,&b);
     84             add(a,b);
     85             
     86         }
     87         for (int i=1;i<=n;i++)
     88         {
     89             if(num[i]==-1)
     90             {
     91                 tarjan(i);
     92             }
     93         }
     94         for (int i=0;i<cnt;i++)
     95         {
     96             int a=e[i].from;
     97             int b=e[i].to;
     98             if(be[a]!=be[b])
     99             {
    100                 in[be[b]]++;
    101                 out[be[a]]++;
    102             }
    103         }
    104         ans1=ans2=0;
    105         for (int i=1;i<=ans;i++)//ans 从1开始。ans为原图强联通分量的个数、
    106         {
    107             if(!in[i])
    108             {
    109                 ans1++;
    110             }
    111             if(!out[i])
    112             {
    113                 ans2++;
    114             }
    115         }
    116         printf("%d
    ",ans==1?0:max(ans1,ans2));    
    117     }
    118     return 0;
    119 }
    120 
    121 /*
    122 
    123 3 2
    124 1 2
    125 2 3
    126 
    127 有3个联通快
    128 
    129 */
  • 相关阅读:
    SAP和ABAP内存的区别
    ABAP如何限制自己开发的耗时报表在sap系统中运行的个数,以保证正常业务的进行
    ABAP如何创建动态结构的报表
    FISAP财务成本知识库
    ABAPSAP显示处理进度的函数
    ABAP如何在REUSE_ALV_GRID_DISPLAY标识不同行用不同的颜色
    Java: 获取当前执行位置的文件名/类名/方法名/行号
    查询不重复的列
    [转载]用SQL语句添加删除修改字段
    [转载]查询之order by,group by和having的使用(一)
  • 原文地址:https://www.cnblogs.com/tingtin/p/9314083.html
Copyright © 2020-2023  润新知