zoukankan      html  css  js  c++  java
  • hdu 2767

    这也是道强连通分量的题;

    题目要求我们求出最少需要添加多少条边让整个图变成一个强连通分量;

    思路很简单,直接缩点,然后找出所有点中有多少出度为0,入度为0的点,最大的那个就是题目所求;

    贴代码:

     1 #include<cstdio>
     2 #include<vector>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<stack>
     6 #define maxn 50005
     7 using namespace std;
     8 vector<int>ve[maxn];
     9 int dfn[maxn],low[maxn],ans,n,m,nncount,b[maxn];
    10 int from[maxn],to[maxn],cntin[maxn],cntout[maxn];
    11 bool instack[maxn];
    12 stack<int>q;
    13 
    14 void tarjin(int x)
    15 {
    16     dfn[x]=low[x]=++nncount;
    17     instack[x]=1;
    18     q.push(x);
    19     int l=ve[x].size();
    20     for(int i=0; i<l; i++)
    21     {
    22         int v=ve[x][i];
    23         if(!dfn[v])
    24         {
    25             tarjin(v);
    26             low[x]=min(low[x],low[v]);
    27         }
    28         else if(instack[v])
    29             low[x]=min(low[x],dfn[v]);
    30     }
    31     if(low[x]==dfn[x])
    32     {
    33         ans++;
    34         int v;
    35         do
    36         {
    37             v=q.top();
    38             q.pop();
    39             b[v]=ans;
    40             instack[v]=0;
    41         }while(v!=x);
    42     }
    43 }
    44 
    45 int main()
    46 {
    47     int x,y,t,mm1,mm2;
    48     scanf("%d",&t);
    49     while(t--)
    50     {
    51         memset(cntin,0,sizeof cntin);
    52         memset(cntout,0,sizeof cntout);
    53         memset(b,0,sizeof b);
    54         memset(dfn,0,sizeof dfn);
    55         memset(low,0,sizeof low);
    56         scanf("%d%d",&n,&m);
    57         for(int i=1; i<=n; i++)
    58         {
    59             ve[i].clear();
    60             instack[i]=0;
    61         }
    62         while(!q.empty()) q.pop();
    63         for(int i=1; i<=m; i++)
    64         {
    65             scanf("%d%d",&x,&y);
    66             ve[x].push_back(y);
    67             from[i]=x,to[i]=y;
    68         }
    69         nncount=ans=mm1=mm2=0;
    70         for(int i=1; i<=n; i++)
    71             if(!dfn[i]) tarjin(i);
    72         if(ans==1){printf("0
    ");continue;}
    73         for(int i=1;i<=m;i++)
    74         {
    75             x=b[from[i]],y=b[to[i]];
    76             if(x!=y) cntout[x]++,cntin[y]++;
    77         }
    78         for(int i=1;i<=ans;i++)
    79         {
    80             if(!cntin[i]) mm1++;
    81             if(!cntout[i]) mm2++;
    82         }
    83         printf("%d
    ",max(mm1,mm2));
    84     }
    85     return 0;
    86 }
    View Code
  • 相关阅读:
    Android 5.0 + IDA 6.8 调试经验分享
    UVA 10003
    欧拉项目010:2000000以内的素数和
    Intellij IDEA 配置Subversion插件
    Intellij IDEA 配置Subversion插件时效解决方法
    javascript 关键字不能作为变量来使用
    JavaScript 闭包(个人理解)
    启动IntelliJ IDEA 2016报错:cannot start under Java 1.7 : Java 1.8 or later is required 解决办法
    jquery easyui tree异步加载子节点
    10.2.1itools导入不了歌曲
  • 原文地址:https://www.cnblogs.com/yours1103/p/3301888.html
Copyright © 2011-2022 走看看