zoukankan      html  css  js  c++  java
  • hdu 1827

    强连通分量——tarjin算法;

    这题的思路就是找出多少个出度为0的连通分量,结果就是这些连通分量的元素的最小值相加;

    一道很简单的题,改了我好久,= =!~

    贴代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<stack>
     5 #include<vector>
     6 #define maxn 1005
     7 using namespace std;
     8 
     9 int dfn[maxn],low[maxn],pen[maxn],b[maxn];
    10 int nncount,ans,cc[maxn],cnt,in[maxn];
    11 bool instack[maxn];
    12 vector<int>ve[maxn];
    13 stack<int>s;
    14 
    15 void tarjin(int x)
    16 {
    17     dfn[x]=low[x]=++nncount;
    18     instack[x]=1;
    19     s.push(x);
    20     int l=ve[x].size();
    21     for(int i=0; i<l; i++)
    22     {
    23         int v=ve[x][i];
    24         if(!dfn[v])
    25         {
    26             tarjin(v);
    27             low[x]=min(low[v],low[x]);
    28         }
    29         else if(instack[v])
    30             low[x]=min(low[x],dfn[v]);
    31     }
    32     if(dfn[x]==low[x])
    33     {
    34         cnt++;
    35         int t;
    36         do
    37         {
    38             t=s.top();
    39             s.pop();
    40             b[t]=cnt;
    41             instack[t]=0;
    42         }
    43         while(t!=x);
    44     }
    45 }
    46 
    47 int main()
    48 {
    49     int n,m,x,y,sum;
    50     while(scanf("%d%d",&n,&m)!=EOF)
    51     {
    52         memset(low,0,sizeof low);
    53         memset(b,0,sizeof b);
    54         memset(dfn,0,sizeof dfn);
    55         memset(in,0,sizeof in);
    56         memset(cc,0,sizeof cc);
    57         memset(instack,0,sizeof instack);
    58         nncount=ans=sum=cnt=0;
    59         for(int i=1; i<=n; i++)
    60         {
    61             scanf("%d",&pen[i]);
    62             ve[i].clear();
    63         }
    64         while(!s.empty()) s.pop();
    65         for(int i=0; i<m; i++)
    66         {
    67             scanf("%d%d",&x,&y);
    68             ve[x].push_back(y);
    69         }
    70         for(int i=1; i<=n; i++)
    71             if(!dfn[i])
    72                 tarjin(i);
    73         for(int i=1; i<=n; i++)
    74         {
    75             int l=ve[i].size();
    76             for(int j=0; j<l; j++)
    77             {
    78                 int v=ve[i][j];
    79                 if(b[i]!=b[v]) in[b[v]]++;
    80             }
    81         }
    82         for(int i=1; i<=cnt; i++)
    83         {
    84             if(in[i]==0)ans++;
    85             cc[i]=999999;
    86         }
    87         for(int i=1; i<=n; i++)
    88         {
    89             int v=b[i];
    90             if(in[v]==0) cc[v]=min(cc[v],pen[i]);
    91         }
    92         for(int i=1; i<=cnt; i++)
    93             if(cc[i]!=999999)
    94                 sum+=cc[i];
    95         printf("%d %d
    ",ans,sum);
    96     }
    97     return 0;
    98 }
    View Code
  • 相关阅读:
    Distributed System
    APP专项测试之兼容性测试
    面试如何正确谈薪?
    跳槽季,如何做好技术面试准备?
    Appium基础
    设置安装程序位置
    获取文件版本号
    28-PV&PVC
    Docker-文件拷贝
    Kubemark压测常用命令
  • 原文地址:https://www.cnblogs.com/yours1103/p/3301901.html
Copyright © 2011-2022 走看看