• UVAlive11324 The Largest Clique(scc+dp)


    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=30726

    【思路】

           强连通分量+动归。

           求scc后缩点,以scc中的节点数作为权值,则问题转化为求一个DAG上的最大权路径,可以用dp求解。

    【代码】

     1 #include<cstdio>
     2 #include<stack>
     3 #include<vector>
     4 #include<cstring>
     5 #include<iostream>
     6 using namespace std;
     7 
     8 const int maxn = 1000+10;
     9 const int maxm = 2000000+10;
    10 
    11 int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;
    12 vector<int> G[maxn];
    13 stack<int> S;
    14 
    15 int dfs(int u) {
    16     pre[u]=lowlink[u]=++dfs_clock;
    17     S.push(u);
    18     for(int i=0;i<G[u].size();i++) {
    19         int v=G[u][i];
    20         if(!pre[v]) {
    21             dfs(v);
    22             lowlink[u]=min(lowlink[u],lowlink[v]);
    23         }
    24         else if(!sccno[v]) {
    25             lowlink[u]=min(lowlink[u],pre[v]);
    26         }
    27     }
    28     if(lowlink[u]==pre[u]) {
    29         scc_cnt++;
    30         for(;;) {
    31             int x=S.top(); S.pop();
    32             sccno[x]=scc_cnt;
    33             if(x==u) break;
    34         }
    35     }
    36 }
    37 void find_scc(int n) {
    38     memset(pre,0,sizeof(pre));
    39     memset(sccno,0,sizeof(sccno));
    40     scc_cnt=dfs_clock=0;
    41     for(int i=0;i<n;i++)  
    42     if(!pre[i]) dfs(i);
    43 }
    44 
    45 int T,n,m;
    46 int val[maxn];
    47 struct Edge{  int u,v,next; } e[maxm];
    48 int en,front[maxm];
    49 void AddEdge(int u,int v) {
    50     en++; e[en].u=u,e[en].v=v; e[en].next=front[u],front[u]=en;
    51 }
    52 
    53 int d[maxn];
    54 int dp(int u) {
    55     int& ans=d[u];
    56     if(ans) return ans;
    57     ans=0;
    58     for(int i=front[u];i>=0;i=e[i].next) {
    59         int v=e[i].v;
    60         ans=max(ans,dp(v));
    61      }
    62     ans+=val[u];
    63     return ans;
    64 }
    65 void init() {
    66     en=-1;
    67     memset(front,-1,sizeof(front));
    68     memset(val,0,sizeof(val));
    69     memset(d,0,sizeof(d));
    70     for(int i=0;i<=n;i++) G[i].clear();
    71 }
    72 int main() {
    73     scanf("%d",&T);
    74     while(T--) {
    75         scanf("%d%d",&n,&m);
    76         init();
    77         int u,v;
    78         for(int i=0;i<m;i++) {
    79             scanf("%d%d",&u,&v);
    80             u--,v--;
    81             G[u].push_back(v);
    82         }
    83         find_scc(n);
    84         for(int i=0;i<n;i++) {
    85             val[sccno[i]]++;
    86             for(int j=0;j<G[i].size();j++) {
    87                 int v=G[i][j];
    88                 if(sccno[i]!=sccno[v]) AddEdge(sccno[i],sccno[v]);
    89             }
    90         }
    91         int ans=0;
    92         for(int i=1;i<=scc_cnt;i++)  ans=max(ans,dp(i));
    93         printf("%d
    ",ans);
    94     }
    95     return 0;
    96 }

    ps:实测该题vector数组式存边较自写邻接表快

  • 相关阅读:
    flex设置成1和auto有什么区别
    在SUBLIME TEXT中安装SUBLIMELINTER进行JS&CSS代码校验
    gulp教程之gulp-less
    sublime注释插件与javascript注释规范
    移动端尺寸基础知识
    webpack入门教程
    IO中同步、异步与阻塞、非阻塞的区别
    Node.js的线程和进程
    Cocos2d-x 3.0中 物理碰撞检測中onContactBegin回调函数不响应问题
    hdu 1789 Doing Homework again 贪心
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5054840.html
Copyright © 2020-2023  润新知