zoukankan      html  css  js  c++  java
  • HDOJ1827解题报告【tarjian强连通分量】

    题目地址:

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

    题目概述:

      中文题就略了。

    大致思路:

      先求出整个图的强连通分量然后缩点,两个scc如果相连则只需要通知一个就好了,统计所有入度为0的scc个数即为最少数量,通知这些scc的最小花费即为答案所求。

    代码:

      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  1010
     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 vector<int> G[maxn];
     29 stack<int> S;
     30 
     31 int pre[maxn],low[maxn],scc[maxn];
     32 int scc_cnt,dfs_clock;
     33 int n,m;
     34 int cost[maxn],ans[maxn],in[maxn];
     35 
     36 void dfs(int u)
     37 {
     38     pre[u]=low[u]=++dfs_clock;
     39     S.push(u);
     40     int len=G[u].size();
     41     for(int i=0;i<len;i++)
     42     {
     43         int v=G[u][i];
     44         if(!pre[v])
     45         {
     46             dfs(v);
     47             low[u]=min(low[u],low[v]);
     48         }
     49         else if(!scc[v]) low[u]=min(low[u],pre[v]);
     50     }
     51     if(pre[u]==low[u])
     52     {
     53         scc_cnt++;
     54         for(;;)
     55         {
     56             int t=S.top();S.pop();
     57             scc[t]=scc_cnt;
     58             if(t==u) break;
     59         }
     60     }
     61 }
     62 
     63 void find_scc()
     64 {
     65     memset(pre,0,sizeof(pre));
     66     memset(low,0,sizeof(low));
     67     memset(scc,0,sizeof(scc));
     68     scc_cnt=0;dfs_clock=0;
     69     for(int i=1;i<=n;i++)
     70         if(!pre[i]) dfs(i);
     71 }
     72 
     73 int main()
     74 {
     75     //freopen("data.in","r",stdin);
     76     //freopen("data.out","w",stdout);
     77     //clock_t st=clock();
     78     while(~scanf("%d%d",&n,&m))
     79     {
     80         int a,b;
     81         for(int i=1;i<=n;i++)
     82         {
     83             G[i].clear();scanf("%d",&cost[i]);
     84         }
     85         for(int i=1;i<=m;i++)
     86         {
     87             scanf("%d%d",&a,&b);
     88             G[a].push_back(b);
     89         }
     90         find_scc();
     91         for(int i=1;i<=scc_cnt;i++) ans[i]=inf,in[i]=0;
     92         for(int i=1;i<=n;i++)
     93             ans[scc[i]]=min(ans[scc[i]],cost[i]);
     94         for(int i=1;i<=n;i++)
     95         {
     96             int len=G[i].size();
     97             for(int k=0;k<len;k++)
     98             {
     99                 int j=G[i][k];
    100                 if(scc[i]!=scc[j]) in[scc[j]]++;
    101             }
    102         }
    103         int cnt=0,sum=0;
    104         for(int i=1;i<=scc_cnt;i++)
    105         {
    106             if(in[i]==0) cnt++,sum+=ans[i];
    107         }
    108         printf("%d %d
    ",cnt,sum);
    109     }
    110     //clock_t ed=clock();
    111     //printf("
    
    Time Used : %.5lf Ms.
    ",(double)(ed-st)/CLOCKS_PER_SEC);
    112     return 0;
    113 }
  • 相关阅读:
    简单的描述关于开发部署产生401,500的错误处理
    文件的批量打包下载
    json的序列化与反序列化
    实现MD5的加密和解密
    dropdownlist的OnSelectedIndexChanged方法不触发
    sqlserver错误2,error 40
    C#存储过程调用的三个方法
    SQL Server 错误:924 解决方法
    判断是否在时间间隔内
    切面添加日志
  • 原文地址:https://www.cnblogs.com/CtrlKismet/p/6598192.html
Copyright © 2011-2022 走看看