zoukankan      html  css  js  c++  java
  • 【UVA11324】The Largest Clique (SCC)

    题意:

      给一张有向图G,求一个结点数最大的结点集,使得该结点中任意两个结点 u 和 v满足:要么 u 可以到达 v, 要么 v 可以到达 u(u 和 v 相互可达也可以)。

    分析:

      Tarjan求SCC缩点,SCC的节点数为新点点权,然后求DAG上权最大的的路径。

    代码如下:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #define Maxn 1010
     5 #define Maxm 50010
     6 
     7 struct node
     8 {
     9     int x,y,next;
    10 }t[Maxm];
    11 
    12 int first[Maxn],dfn[Maxn],low[Maxn],sta[Maxn],scc[Maxn],sum[Maxn];
    13 bool bj[Maxn],bj2[Maxn],map[Maxn][Maxn];
    14 int cnt,sl,cl;
    15 
    16 int mymin(int x,int y) {return x<y?x:y;}
    17 int mymax(int x,int y) {return x>y?x:y;}
    18 
    19 void ffind(int x)
    20 {
    21     dfn[x]=low[x]=++cnt;
    22     sta[++sl]=x;
    23     for(int i=first[x];i;i=t[i].next)
    24     {
    25         int y=t[i].y;
    26         if(dfn[y]==0)
    27         {
    28             ffind(y);
    29             low[x]=mymin(low[x],low[y]);
    30         }
    31         else if(scc[y]==0) low[x]=mymin(low[x],dfn[y]);
    32     }
    33     if(dfn[x]==low[x])
    34     {
    35         cl++;
    36         while(1)
    37         {
    38             int z=sta[sl--];
    39             scc[z]=cl;
    40             sum[cl]++;
    41             if(z==x) break;
    42         }
    43     }
    44 }
    45 
    46 int dfs(int x)
    47 {
    48     int ans=0;
    49     bj[x]=1;
    50     for(int i=1;i<=cl;i++) if(map[x][i]==1&&bj[i]==0)
    51      ans=mymax(ans,dfs(i));
    52     ans+=sum[x];
    53     bj[x]=0;
    54     return ans;
    55 }
    56 
    57 int main()
    58 {
    59     int T;
    60     scanf("%d",&T);
    61     while(T--)
    62     {
    63         int n,m,ans=0;
    64         scanf("%d%d",&n,&m);
    65         memset(first,0,sizeof(first));
    66         memset(dfn,0,sizeof(dfn));
    67         memset(sum,0,sizeof(sum));
    68         memset(bj,0,sizeof(bj));
    69         memset(map,0,sizeof(map));
    70         memset(scc,0,sizeof(scc));
    71         cnt=0;sl=0;cl=0;
    72         for(int i=1;i<=m;i++)
    73         {
    74             int x,y;
    75             scanf("%d%d",&t[i].x,&t[i].y);
    76             t[i].next=first[t[i].x];first[t[i].x]=i;
    77         }
    78         for(int i=1;i<=n;i++) if(dfn[i]==0) ffind(i);
    79         for(int i=1;i<=m;i++) if(scc[t[i].x]!=scc[t[i].y]) map[scc[t[i].x]][scc[t[i].y]]=1;
    80         for(int i=1;i<=cl;i++) ans=mymax(ans,dfs(i));
    81         printf("%d
    ",ans);
    82     }
    83     return 0;
    84 }
    UVA11324

    2016-03-17 16:54:20

  • 相关阅读:
    golang学习之旅:使用go语言操作mysql数据库
    golang操作mysql使用总结
    win7环境搭建以太坊私链
    golang面试题--string操作
    如何获得微信小游戏源码
    [Egret]长按截屏分享、分享截屏图片、本地存储
    android 6.0导航栏 NavigationBar影响视图解决办法
    android设置透明状态栏
    理解Android中的注解与反射
    Butter Knife
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5288068.html
Copyright © 2011-2022 走看看