• UVA11324 The Largest Clique (强连通缩点+DP最长路)


    <题目链接>

    题目大意:

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

    解题分析:

    该点集需满足两个要求:1.任意两点至少有一方能够到达另外一点;2.点数尽可能的多。

    通过画图分析可以知道,对于那些强连通分量来说,要不就全部加入该点集,要不就全部不能加入,所以直接对原图进行缩点,进行重新构图。然后,根据重新构造的DAG图我们可以知道,要使该点集中任意两点至少有一方能够到达另外一点,并且要求点数尽可能的多,可以发现,其实就是让我们求缩点后的最长路。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <vector>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 #define pb push_back
     8 #define clr(a,b) memset(a,b,sizeof(a))
     9 #define rep(i,s,t) for(int i=s;i<=t;i++)
    10 const int N = 1e3+10,M = 5e4+10;
    11 int n,m,tot,tott,top,scc;
    12 int head[N],belong[N],dfn[N],low[N],stk[N],instk[N],dp[N],cnt[N];
    13 vector<int>G[N];
    14 struct Edge{
    15     int to,next;
    16 }edge[M];
    17 void init(){
    18     rep(i,0,n)G[i].clear();
    19     tot=scc=top=tott=0;
    20     clr(head,-1);clr(low,0);clr(dfn,0);clr(stk,0);clr(instk,0);clr(belong,0);clr(dp,0);clr(cnt,0);
    21 }
    22 void addedge(int u,int v){
    23     edge[++tot].to=v,edge[tot].next=head[u];
    24     head[u]=tot;
    25 }
    26 void Tarjan(int u){       //进行缩点
    27     dfn[u]=low[u]=++tott;
    28     stk[++top]=u;instk[u]=1;
    29     for(int i=head[u];~i;i=edge[i].next){
    30         int v=edge[i].to;
    31         if(!dfn[v]){
    32             Tarjan(v);
    33             low[u]=min(low[u],low[v]);
    34         }else if(instk[v])low[u]=min(low[u],dfn[v]);
    35     }
    36     if(dfn[u]==low[u]){
    37         scc++;
    38         while(true){
    39             int v=stk[top--];
    40             instk[v]=0;
    41             belong[v]=scc;
    42             cnt[scc]++;
    43             if(v==u)break;
    44         }
    45     }
    46 }
    47 //记忆化搜索求以u为起点的最长路,点权为"点"中点的个数
    48 int DFS(int u){
    49     if(dp[u])return dp[u];
    50     int ans=cnt[u];
    51     for(int i=0;i<G[u].size();i++){
    52         int v=G[u][i];
    53         ans=max(ans,DFS(v)+cnt[u]);
    54     }
    55     return dp[u]=ans;
    56 }
    57 int main(){
    58     int T;scanf("%d",&T);while(T--){
    59         init(); 
    60         scanf("%d%d",&n,&m);
    61         rep(i,1,m){
    62             int u,v;scanf("%d%d",&u,&v);
    63             addedge(u,v);
    64         }
    65         rep(i,1,n)
    66             if(!dfn[i])Tarjan(i);
    67         //对图进行缩点,重新构图
    68         rep(u,1,n) for(int i=head[u];~i;i=edge[i].next){
    69             int v=edge[i].to;
    70             if(belong[u]!=belong[v])
    71                 G[belong[u]].pb(belong[v]);
    72         }
    73         int ans=0;
    74         rep(i,1,scc)
    75             ans=max(ans,DFS(i));   //求缩点后图的最长路
    76         printf("%d
    ",ans);
    77     }
    78 }

    2018-11-28

  • 相关阅读:
    安装DotNetCore.1.0.1-VS2015Tools.Preview2.0.2出现0x80072f8a未指定的错误
    [迷宫中的算法实践]迷宫生成算法——Prim算法
    [MVC学习笔记]7.使用极验验证来制作更高逼格的验证码
    Android UI--提高Android UI体验
    Genymotion的使用 -- A Faster Android Emulator
    【Xamarin】Visual Studio 2013 Xamarin for Android开发环境搭建与配置&Genymotion
    【ASP.NET Web API2】利用HttpClient调用Web API(TODO)
    VMware 11 安装 Mac OS X10.10
    ASP.NET MVC 缓存Outputcache (局部动态)
    【ASP.NET Web API2】初识Web API
  • 原文地址:https://www.cnblogs.com/00isok/p/10034504.html
Copyright © 2020-2023  润新知