• The Largest Clique UVA


    题文:https://vjudge.net/problem/UVA-11324

    题解:

      这个题目首先可以发现,只要是一个强连通分量,要么都选,要么都不选,将点权看成强连通分量的点数,所以这个题目就转化成了DAG上的最大路。

      稍微dp一下就好了。

    代码:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <stack>
    #define MAXN 50100
    using namespace std;
    struct edge{
        int first;
        int next;
        int to;
    }a[MAXN*2];
    int dfn[MAXN],in[MAXN],low[MAXN],fa[MAXN],size[MAXN];
    int dp[MAXN],b[MAXN],x[MAXN],y[MAXN];
    int n,m,num1=0,num2=0,num3=0;
    stack<int> s;
    
    void cl(){
        memset(low,0,sizeof(low));
        memset(dp,0,sizeof(dp));
        memset(dfn,0,sizeof(dfn));
        memset(fa,0,sizeof(fa));
        memset(size,0,sizeof(size));
        memset(a,0,sizeof(a));num1=num2=num3=0;
        memset(in,0,sizeof(in));
        memset(b,0,sizeof(b));
        memset(x,0,sizeof(x));
        memset(y,0,sizeof(y));
    }
    
    void addedge(int from,int to){
        a[++num1].to=to;
        a[num1].next=a[from].first;
        a[from].first=num1;
    }
    
    void init(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&x[i],&y[i]);
            addedge(x[i],y[i]);
        }
    }
    
    void tarjian(int now){
        s.push(now);in[now]=1;
        dfn[now]=low[now]=++num3;
        for(int i=a[now].first;i;i=a[i].next){
            int to=a[i].to;
            if(!dfn[to]){
                tarjian(to);
                low[now]=min(low[now],low[to]);
            }
            else if(in[to]) low[now]=min(low[now],dfn[to]);
        }
        if(low[now]==dfn[now]){
            int u=-1;
            num2++;
            while(u!=now){
                u=s.top();s.pop();in[u]=0;
                fa[u]=num2;
                size[num2]++;
            }
        }
    }
    
    void make(){
        memset(a,0,sizeof(a));num1=0;
        for(int i=1;i<=m;i++){
            if(fa[x[i]]!=fa[y[i]]) addedge(fa[x[i]],fa[y[i]]);
        }
    }
    
    void pre(){
        while(!s.empty()) s.pop();
        for(int i=1;i<=n;i++) if(!dfn[i]) tarjian(i);
        make();
    }
    
    int DP(int now){
        if(b[now]) return dp[now];
        b[now]=1;
        dp[now]+=size[now];
        for(int i=a[now].first;i;i=a[i].next){
            int to=a[i].to;
            dp[now]=max(dp[now],size[now]+DP(to));
        }
        return dp[now];
    }
    
    int main()
    {
        int t;cin>>t;
        while(t--){
            cl();
            init();
            pre();
            for(int i=1;i<=n;i++) DP(i);
            int ans=0;
            for(int i=1;i<=n;i++) ans=max(ans,dp[i]);
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    java控制台输入
    冒泡排序
    选择排序
    Json数组去重
    HTTP状态码详解
    根据json对象的值替换json数组里的值
    用户中心页面
    正则表达式
    vue-router如何根据不同的用户给不同的权限
    vue2.0+element+node+webpack搭建的一个简单的后台管理界面
  • 原文地址:https://www.cnblogs.com/renjianshige/p/7512542.html
Copyright © 2020-2023  润新知