zoukankan      html  css  js  c++  java
  • HDOJ3639解题报告【缩点+dfs】

    题目地址:

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

    题目概述:

      题面有点翻译不来……可以用Chrome自带的那个翻译。

    大致思路:

      如果跑bfs或者dfs遇到环的话就会出问题,所以先跑一遍tarjan求强连通分量,把环的情况去掉,在剩下的图上做。

      这个时候发现样例1里2这个节点指向的两个节点都是答案,所以反向建图,用dfs求出所有入度为0的点的子树大小,最大数即为答案。

      输出节点的时候直接对0~n-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  5010
     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 vector<int> rG[maxn];
     30 stack<int> S;
     31 
     32 struct node
     33 {
     34     int pos,val;
     35     bool operator < (const node &a) const
     36     {
     37         return val<a.val;
     38     }
     39 };
     40 
     41 int pre[maxn],low[maxn],scc[maxn],scc_val[maxn];
     42 int scc_cnt,dfs_clock;
     43 int n,m;
     44 int ans[maxn],in[maxn],cnt[maxn],vis[maxn];
     45 
     46 void dfs(int u)
     47 {
     48     pre[u]=low[u]=++dfs_clock;
     49     int len=G[u].size();S.push(u);
     50     for(int i=0;i<len;i++)
     51     {
     52         int v=G[u][i];
     53         if(!pre[v])
     54         {
     55             dfs(v);
     56             low[u]=min(low[u],low[v]);
     57         }
     58         else if(!scc[v]) low[u]=min(low[u],pre[v]);
     59     }
     60     if(pre[u]==low[u])
     61     {
     62         scc_cnt++;int cnt=0;
     63         for(;;)
     64         {
     65             int t=S.top();S.pop();
     66             scc[t]=scc_cnt;cnt++;
     67             if(t==u) break;
     68         }
     69         scc_val[scc_cnt]=cnt;
     70     }
     71 }
     72 
     73 void find_scc()
     74 {
     75     memset(pre,0,sizeof(pre));
     76     memset(low,0,sizeof(low));
     77     memset(scc,0,sizeof(scc));
     78     scc_cnt=0;dfs_clock=0;
     79     for(int i=1;i<=n;i++)
     80     {
     81         if(!pre[i]) dfs(i);
     82     }
     83 }
     84 
     85 int Count(int u)
     86 {
     87     vis[u]=1;
     88     int len=rG[u].size(),sum=scc_val[u];
     89     for(int i=0;i<len;i++)
     90     {
     91         int v=rG[u][i];
     92         if(!vis[v]) sum+=Count(v);
     93     }
     94     return sum;
     95 }
     96 
     97 int main()
     98 {
     99     //freopen("data.in","r",stdin);
    100     //freopen("data.out","w",stdout);
    101     //clock_t st=clock();
    102     int T;scanf("%d",&T);
    103     for(int kase=1;kase<=T;kase++)
    104     {
    105         int a,b;scanf("%d%d",&n,&m);
    106         for(int i=1;i<=n;i++)
    107         {
    108             G[i].clear();
    109         }
    110         for(int i=1;i<=m;i++)
    111         {
    112             scanf("%d%d",&a,&b);
    113             a++;b++;G[a].push_back(b);
    114         }
    115         find_scc();
    116 
    117         ///缩点
    118         for(int i=1;i<=scc_cnt;i++)
    119         {
    120             in[i]=0;cnt[i]=-1;
    121             rG[i].clear();
    122         }
    123         for(int i=1;i<=n;i++)
    124         {
    125             for(int j=1;j<=scc_cnt;j++) vis[j]=0;
    126             int len=G[i].size();
    127             for(int k=0;k<len;k++)
    128             {
    129                 int j=G[i][k];
    130                 if(scc[i]!=scc[j]&&!vis[scc[j]])
    131                 {
    132                     vis[scc[j]]=1;rG[scc[j]].push_back(scc[i]);
    133                     in[scc[i]]++;
    134                 }
    135             }
    136         }
    137 
    138         int ans=-1;bool flag=false;
    139         for(int i=1;i<=scc_cnt;i++)
    140         {
    141             if(!in[i])
    142             {
    143                 for(int j=1;j<=scc_cnt;j++) vis[j]=0;
    144                 cnt[i]=Count(i);ans=max(ans,cnt[i]);
    145             }
    146         }
    147         printf("Case %d: %d
    ",kase,ans-1);
    148         for(int i=1;i<=n;i++)
    149         {
    150             if(ans==cnt[scc[i]])
    151             {
    152                 if(flag) printf(" ");
    153                 printf("%d",i-1);flag=true;
    154             }
    155         }
    156         printf("
    ");
    157     }
    158     //clock_t ed=clock();
    159     //printf("
    
    Time Used : %.5lf Ms.
    ",(double)(ed-st)/CLOCKS_PER_SEC);
    160     return 0;
    161 }
  • 相关阅读:
    【转】突破区块链不可能三角:异步共识组 [Monoxide]
    [转]王嘉平:Monoxide 原理详解,如何用极简架构突破不可能三角
    【转】区块链公链的 3 大性能难点、5 大体验障碍
    使用ShowDoc在线管理API接口文档
    云和恩墨大讲堂电子刊2019年4月刊发布
    墙裂推荐 | 漫画解读Elasticsearch原理,看完你就懂
    DBASK数据库提问平台问题集萃,首批近二十位专家团曝光
    WIN10安装GPU版tensorflow
    cobbler的网页操作
    cobbler的网页操作
  • 原文地址:https://www.cnblogs.com/CtrlKismet/p/6610190.html
Copyright © 2011-2022 走看看