zoukankan      html  css  js  c++  java
  • UVA 11324 The Largest Clique(缩点+DAG上的dp)

    求最大团。和等价性证明有类似之处,只不过这个不是求互推,而是只要a->b,或b->a即可。

    同样的,容易想到先缩点,得到DAG,每个节点上保存SCC的点数,相信任意一条由根节点(入度为零)出发的路径中权值和最大的即为所求,dp即可解决。

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stack>
      4 #include<algorithm>
      5 using namespace std;
      6 
      7 const int MAXN=1111;
      8 const int MAXM=55555;
      9 
     10 struct Edge{
     11     int v,next;
     12 }edge[MAXM];
     13 
     14 stack<int >stk;
     15 int head[MAXN],tol;
     16 int low[MAXN],pre[MAXN],sccno[MAXN],scc_cnt,TT,sccnum[MAXN];
     17 int dp[MAXN];
     18 
     19 void init()
     20 {
     21     tol=0;
     22     memset(head,-1,sizeof(head));
     23 }
     24 
     25 void add(int u,int v)
     26 {
     27     edge[tol].v=v;
     28     edge[tol].next=head[u];
     29     head[u]=tol++;
     30 }
     31 
     32 void dfs(int u)
     33 {
     34     int v;
     35     low[u]=pre[u]=++TT;
     36     stk.push(u);
     37     for(int i=head[u];i!=-1;i=edge[i].next)
     38     {
     39         v=edge[i].v;
     40         if(!pre[v]){
     41             dfs(v);
     42             low[u]=min(low[u],low[v]);
     43         }else if(!sccno[v])
     44             low[u]=min(low[u],pre[v]);
     45     }
     46     if(low[u]==pre[u]){
     47         scc_cnt++;
     48         int s=0;
     49         do{
     50             v=stk.top();
     51             stk.pop();
     52             sccno[v]=scc_cnt;
     53             s++;
     54         }while(u!=v);
     55         sccnum[scc_cnt]=s;
     56     }
     57 }
     58 
     59 void tarjan(int n)
     60 {
     61     scc_cnt=TT=0;
     62     memset(low,0,sizeof(low));
     63     memset(pre,0,sizeof(pre));
     64     memset(sccno,0,sizeof(sccno));
     65 
     66     for(int i=1;i<=n;i++)
     67         if(!pre[i])
     68             dfs(i);
     69 }
     70 
     71 int find_dfs(int u){
     72     if(dp[u])
     73         return dp[u];
     74     else if(head[u]==-1)
     75         return dp[u]=sccnum[u];
     76 
     77     int m=0;
     78     for(int i=head[u];i!=-1;i=edge[i].next)
     79     {
     80         int v=edge[i].v;
     81         m=max(m,find_dfs(v));
     82     }
     83     return dp[u]=sccnum[u]+m;
     84 }
     85 
     86 int main()
     87 {
     88     int T,n,m;
     89     int a[MAXM],b[MAXM];
     90     int in[MAXN];
     91     scanf("%d",&T);
     92     while(T--)
     93     {
     94         scanf("%d%d",&n,&m);
     95 
     96         init();
     97         for(int i=1;i<=m;i++)
     98         {
     99             scanf("%d%d",&a[i],&b[i]);
    100             add(a[i],b[i]);
    101         }
    102         tarjan(n);
    103 
    104         init();
    105         memset(in,0,sizeof(in));
    106         for(int i=1;i<=m;i++)
    107         {
    108             if(sccno[a[i]]!=sccno[b[i]]){
    109                 in[sccno[b[i]]]++;
    110                 add(sccno[a[i]],sccno[b[i]]);
    111             }
    112         }
    113         int s=0;
    114         memset(dp,0,sizeof(dp));
    115         for(int i=1;i<=scc_cnt;i++)
    116             if(!in[i])
    117                 s=max(s,find_dfs(i));
    118         printf("%d
    ",s);
    119     }
    120     return 0;
    121 }
    View Code
  • 相关阅读:
    android开发中如何开启用户安装的应用程序?
    丑数查找算法
    session.save_path目录大量session临时文件带来的服务器效率问题
    MOSS点滴(1):如何开发和部署feature
    如何将Excel中两个单元格或两列中的数据合并
    如何在 MOSS 2007 启用 Session
    MOSS LIST的一些属性说明
    国外广播电台
    Excel 导出 按钮
    在文档库或 Windows SharePoint Services SharePoint Portal Server 中创建一个新的文件夹或新文档时,您会收到一个"指定的文件或文件夹名太长"错误消息
  • 原文地址:https://www.cnblogs.com/zstu-abc/p/3239803.html
Copyright © 2011-2022 走看看