zoukankan      html  css  js  c++  java
  • hdu 3639 强连通练习使用

    题意很明显,就是说现在有n个孩子正在玩游戏,完成一个传递的游戏,举个例子,A传递到B小朋友,然后B小朋友传递给C小朋友,那么此时,C小朋友将拥有2的传递值,C是胜利者,若C又传递回A,那么A,B,C三者都拥有传递值为2的胜利者,说白了就是强连通的一个练习。

    思路就是分清楚这整个图当中的强连通分量,每个分量包含了哪些点,将这些分量缩成一个点,然后建立这些点的一个反向图,然后每次从入度为0的强连通分量深搜,最后标记哪些强连通分量为max。那么只要该点所属的强连通分量为max,那么该点,也就是该小朋友就是赢家。。

    View Code
      1   #include<iostream>
      2   #define min(a,b) a<b?a:b
      3   #define max(a,b) a>b?a:b
      4   using namespace std;
      5   struct node
      6   {
      7       int s,e,next;       
      8   }edge1[500002],edge2[500002];
      9   int head1[5002],head2[5002],dfn[5002],low[5002],stack[5002],exsit[5002],weight[5002],color[5002],n,m,s,e,top,Count,Time;
     10   int ind[5002],Max,sum;
     11   void tarjan(int u)
     12   {
     13        dfn[u]=low[u]=++Time;
     14        stack[top++]=u;
     15        exsit[u]=1;
     16        for(int end=head1[u];end!=-1;end=edge1[end].next)
     17        {
     18             if(!dfn[edge1[end].e])
     19             {
     20                 tarjan(edge1[end].e);
     21                 low[u]=min(low[u],low[edge1[end].e]);
     22             }
     23             else
     24              if(exsit[edge1[end].e]==1)
     25              low[u]=min(low[u],dfn[edge1[end].e]);
     26        }
     27        if(dfn[u]==low[u])
     28        {
     29            Count++;
     30            int v;
     31            do
     32            {
     33                v=stack[top-1];
     34                exsit[v]=0;
     35                weight[v]=Count;
     36                color[Count]++;
     37                top--;
     38            }while(u!=v);
     39            
     40        }
     41   }
     42   void dfs(int i)
     43   {
     44       sum+=color[i];
     45       exsit[i]=1;
     46       Max=max(Max,sum);
     47       for(int j=head2[i];j!=-1;j=edge2[j].next)
     48       {
     49             if(exsit[edge2[j].e]==0)
     50             {
     51                dfs(edge2[j].e);                   
     52             }
     53       }
     54       return ;
     55   }
     56   int main()
     57   {
     58      int t,T=0;
     59      scanf("%d",&t);
     60      while(t--)
     61      {
     62             scanf("%d%d",&n,&m);
     63             for(int i=0;i<=n;i++)
     64             {
     65                  head1[i]=head2[i]=-1;
     66                  color[i]=weight[i]=exsit[i]=dfn[i]=low[i]=0;
     67             }
     68             for(int i=0;i<m;i++)
     69             {
     70                 scanf("%d%d",&s,&e);
     71                 edge1[i].s=s;
     72                 edge1[i].e=e;
     73                 edge1[i].next=head1[s];
     74                 head1[s]=i;
     75             }
     76             Time=top=Count=0;
     77             for(int i=0;i<n;i++)
     78             {
     79                 if(!dfn[i])
     80                 {
     81                   tarjan(i);
     82                 }
     83             }
     84             for(int i=1;i<=Count;i++)
     85             {
     86                dfn[i]=ind[i]=0;
     87             }
     88             Time=0;
     89             for(int i=0;i<m;i++)
     90             {
     91                   int start=weight[edge1[i].s];
     92                   int end=weight[edge1[i].e];
     93                   if(start!=end)
     94                   {
     95                         edge2[Time].e=start;
     96                         edge2[Time].next=head2[end];
     97                         head2[end]=Time++;
     98                         ind[start]++;
     99                   }
    100             }
    101             int maxsize=0;
    102             for(int i=1;i<=Count;i++)
    103             {
    104                
    105                if(ind[i]==0)
    106                {
    107                  for(int j=1;j<=Count;j++)exsit[j]=0;
    108                  Max=sum=0;
    109                  dfs(i);
    110                  dfn[i]=Max;
    111                  maxsize=max(dfn[i],maxsize);
    112                }
    113             }
    114             int flag=0;
    115             printf("Case %d: %d\n",++T,maxsize-1);
    116             for(int i=0;i<n;i++)
    117             {
    118                if(dfn[weight[i]]==maxsize)
    119                {
    120                    if(!flag){printf("%d",i);flag=1;}
    121                    else
    122                    printf(" %d",i);
    123                }        
    124             }
    125             printf("\n");
    126      }
    127      return 0;
    128   }
  • 相关阅读:
    Windows API 中 OVERLAPPED 结构体 初始化
    QString 转换成 wchar 的一个小陷阱
    Windows VHD Create, Attach, 获得Disk序号
    Programmatically mount a Microsoft Virtual Hard Drive (VHD)
    chcp437 转换英语,在西班牙语系统中无效
    Windows 版本 Enterprise、Ultimate、Home、Professional
    openssl 查看证书
    Ubuntu 搜索文件
    微软的 Sysinternals 系统管理工具包,例如可找出自动启动的流氓软件
    HTML 表格实例
  • 原文地址:https://www.cnblogs.com/nuoyan2010/p/2667106.html
Copyright © 2011-2022 走看看