zoukankan      html  css  js  c++  java
  • UVa 11234 The Largest Clique

    找最长的连接的点的数量。用tarjan缩点,思考可知每一个强连通分量里的点要么都选,要么都不选(走别的路),可以动规解决。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<vector>
     5 #include<cstring>
     6 using namespace std;
     7 const int mxn=12000;
     8 int top,stack[mxn];
     9 bool inst[mxn];
    10 int cnt,dnow; 
    11 int dfn[mxn],low[mxn];
    12 int belone[mxn];
    13 int ptcnt[mxn];
    14 int dp[mxn];
    15 vector<int> e[mxn];//邻接表 
    16 vector<int> pt[mxn];//缩点后的点集 
    17 void clear(){
    18     cnt=0;dnow=0;top=0;
    19     memset(dfn,-1,sizeof(dfn));
    20     memset(inst,false,sizeof(inst));
    21     memset(dp,0,sizeof dp);
    22     memset(ptcnt,0,sizeof ptcnt);
    23     memset(belone,0,sizeof belone);
    24     for(int i=1;i<mxn;i++) e[i].clear();
    25     for(int i=1;i<mxn;i++) pt[i].clear();
    26 }
    27 int n,m;
    28 void tarjan(int s){
    29     int v=0,i;
    30     dfn[s]=++dnow;
    31     low[s]=dfn[s];
    32     inst[s]=true; 
    33     stack[++top]=s;
    34     int si=e[s].size();
    35     for(i=0;i<si;i++){
    36         v=e[s][i];
    37         if(dfn[v]==-1){
    38             tarjan(v);
    39             low[s]=min(low[v],low[s]);
    40         }
    41         else if(inst[v]){
    42             low[s]=min(dfn[v],low[s]);
    43         }
    44     }
    45     if(dfn[s]==low[s]){
    46         cnt++;
    47         do{
    48             v=stack[top--];
    49             belone[v]=cnt;
    50             inst[v]=false;
    51         }while(s!=v);
    52     }
    53     return;
    54 }
    55 int find(int x){//动规 
    56     if(pt[x].size()==0)return dp[x]=ptcnt[x];
    57     if(dp[x])return dp[x];
    58     int mx=0;
    59     for(int i=0;i<pt[x].size();i++){
    60         mx=max(mx,find(pt[x][i]));
    61     }
    62     dp[x]=mx+ptcnt[x];
    63     return dp[x];
    64 }
    65 void solve(){//统计缩完点之后的连通情况 
    66     int i,j,k;
    67     for(i=1;i<=n;i++){
    68         ptcnt[belone[i]]++;
    69         for(j=0;j<e[i].size();j++){
    70             int v=e[i][j];
    71             if(belone[i]!=belone[v])
    72                 pt[belone[i]].push_back(belone[v]);
    73         }
    74     }
    75     int ans=0;
    76     for(i=1;i<=cnt;i++)ans=max(ans,find(i));
    77     printf("%d
    ",ans);
    78     return;
    79 }
    80 int main(){
    81     int T;
    82     scanf("%d",&T);
    83     while(T--){
    84         scanf("%d%d",&n,&m);
    85         clear();
    86         int i,j;
    87         int u,v;
    88         for(i=1;i<=m;i++){
    89             scanf("%d%d",&u,&v);
    90             e[u].push_back(v);
    91         }
    92         for(i=1;i<=n;i++){//缩点 
    93             if(dfn[i]==-1)tarjan(i);
    94         }
    95         solve();
    96     }
    97     return 0;
    98 }
  • 相关阅读:
    浅析 KMP
    【GOJ 3049】玩具
    较详细的gdb入门教程
    【GOJ 2963】记者
    【GOJ 2961】数数
    GF OIer's Talk 维护笔记
    Linux 中 UFW 的使用
    开源是什么?能吃吗?
    个人介绍
    NOIP2020 爆零记
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5746531.html
Copyright © 2011-2022 走看看