zoukankan      html  css  js  c++  java
  • HDOJ2767、3836解题报告【强连通分量】

    题目地址:

      http://acm.hdu.edu.cn/showproblem.php?pid=2767

      http://acm.hdu.edu.cn/showproblem.php?pid=3836

    题目概述:

      给出一张有向图,添加最少的边使这张图强连通,求最少需要添加的边数。

      3836跟2767的题面只有输入数据的方式差别,注意一下就可以了。

    大致思路:

      先求出整个图的强连通分量然后缩点,在新图中统计出度为0和入度为0的点的个数,最大值即为答案。

      有些小细节需要注意,如果原图强连通应该输出0而不是1.

    代码:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cmath>
      5 #include <vector>
      6 #include <ctime>
      7 #include <map>
      8 #include <stack>
      9 #include <queue>
     10 #include <cstring>
     11 #include <algorithm>
     12 using namespace std;
     13 
     14 #define sacnf scanf
     15 #define scnaf scanf
     16 #define maxn  20010
     17 #define maxm 26
     18 #define inf 1061109567
     19 #define Eps 0.00001
     20 const double PI=acos(-1.0);
     21 #define mod 7
     22 #define MAXNUM 10000
     23 void Swap(int &a,int &b) {int t=a;a=b;b=t;}
     24 int Abs(int x) {return (x<0)?-x:x;}
     25 typedef long long ll;
     26 typedef unsigned int uint;
     27 
     28 int n,m;
     29 vector<int> G[maxn];
     30 stack<int> S;
     31 
     32 int pre[maxn],low[maxn],scc[maxn];
     33 int dfs_clock,scc_cnt;
     34 int in[maxn],out[maxn];
     35 
     36 void dfs(int u)
     37 {
     38     pre[u]=low[u]=++dfs_clock;
     39     int len=G[u].size();S.push(u);
     40     for(int i=0;i<len;i++)
     41     {
     42         int v=G[u][i];
     43         if(!pre[v])
     44         {
     45             dfs(v);
     46             low[u]=min(low[u],low[v]);
     47         }
     48         else if(!scc[v]) low[u]=min(low[u],pre[v]);
     49     }
     50     if(pre[u]==low[u])
     51     {
     52         scc_cnt++;
     53         for(;;)
     54         {
     55             int t=S.top();S.pop();
     56             scc[t]=scc_cnt;
     57             if(t==u) break;
     58         }
     59     }
     60 }
     61 
     62 void find_scc()
     63 {
     64     memset(pre,0,sizeof(pre));
     65     memset(low,0,sizeof(low));
     66     memset(scc,0,sizeof(scc));
     67     dfs_clock=0;scc_cnt=0;
     68     for(int i=1;i<=n;i++)
     69         if(!pre[i]) dfs(i);
     70 }
     71 
     72 int main()
     73 {
     74     //freopen("data.in","r",stdin);
     75     //freopen("data.out","w",stdout);
     76     //clock_t st=clock();
     77     int T;scanf("%d",&T);
     78     while(T--)
     79     {
     80         scanf("%d%d",&n,&m);
     81         int a,b;
     82         for(int i=1;i<=n;i++) G[i].clear();
     83         for(int i=1;i<=m;i++)
     84         {
     85             scanf("%d%d",&a,&b);
     86             G[a].push_back(b);
     87         }
     88         find_scc();
     89         for(int i=1;i<=scc_cnt;i++) in[i]=out[i]=0;
     90         for(int i=1;i<=n;i++)
     91         {
     92             int len=G[i].size();
     93             for(int k=0;k<len;k++)
     94             {
     95                 int j=G[i][k];
     96                 if(scc[i]==scc[j]) continue;
     97                 in[scc[j]]++;out[scc[i]]++;
     98             }
     99         }
    100         int ans1=0,ans2=0;
    101         for(int i=1;i<=scc_cnt;i++)
    102         {
    103             if(!in[i]) ans1++;
    104             if(!out[i]) ans2++;
    105         }
    106         printf("%d
    ",(scc_cnt==1)?0:max(ans1,ans2));
    107     }
    108     //clock_t ed=clock();
    109     //printf("
    
    Time Used : %.5lf Ms.
    ",(double)(ed-st)/CLOCKS_PER_SEC);
    110     return 0;
    111 }
  • 相关阅读:
    kmeans 聚类
    HTTP与HTTPS相关知识
    如何和统计学家分享数据How to share data with a statistician
    使用 Python 进行 T检验
    Jupyter Lab目录插件安装
    【Python项目】爬取新浪微博个人用户信息页
    【Python项目】爬取新浪微博签到页
    使用SVN服务器管理源码
    [转载]C++命名规则
    C++&OpenCV中读取灰度图像到数组的两种
  • 原文地址:https://www.cnblogs.com/CtrlKismet/p/6610102.html
Copyright © 2011-2022 走看看