zoukankan      html  css  js  c++  java
  • Uva 11324 最大团

    题目链接:http://vjudge.net/contest/141990#problem/B

    题意:

    给一张有向图G,求一个结点集数最大的结点集,是的该结点集中任意两个结点 u 和 v,满足: 要么 u 能到达 v,要么 v 能到达 u 或者 u 和 v 可以互达 ;

    这个和有向强连通图很像,连通方式改了,强连通分量是 任意 两点 之间 都可以互达。可以发现一个强连通分量 ,要么全选,要么全部选。

    思路:

    把一个强连通分量看成一个结点,这个结点有权值,是他的大小,把每个强连通分量看成一个结点,这样 SCC 图就出来了,SCC图 他是一个有向无环图 DAG。

    于是就可以用 dp 来做。

    坑点:(数据有可能一个结点都没有)

    #include <bits/stdc++.h>
    using namespace std;
    
    const int Maxn = 1000 + 10;
    
    vector<int> G[Maxn];
    int pre[Maxn];
    int lowlink[Maxn];
    int sccno[Maxn];
    int dfs_clock;
    int scc_cnt;
    int n,m;
    
    stack<int> S;
    
    void dfs(int u)
    {
        pre[u] = lowlink[u] = ++dfs_clock;
        S.push(u);
        for(int i = 0; i < G[u].size(); i++)
        {
            int v = G[u][i];
            if(!pre[v])
            {
                dfs(v);
                lowlink[u] = min(lowlink[u], lowlink[v]);
            }
            else if(!sccno[v])
            {
                lowlink[u] = min(lowlink[u], pre[v]);
            }
        }
        if(lowlink[u] == pre[u])
        {
            scc_cnt++;
            for(;;)
            {
                int x = S.top();
                S.pop();
                sccno[x] = scc_cnt;
                if(x == u) break;
            }
        }
    }
    
    
    void find_scc(int)
    {
        dfs_clock = scc_cnt = 0;
        memset(pre,0,sizeof(pre));
        memset(sccno,0,sizeof(sccno));
    
        for(int i=0; i<n; i++)
        {
            if(!pre[i])
                dfs(i);
        }
    }
    
    int size[Maxn], TG[Maxn][Maxn];
    int d[Maxn];
    
    int dp(int u)
    {
        int& ans = d[u];
        if(ans >= 0) return ans;
        ans = size[u];
        for(int v = 1; v <= scc_cnt; v++)
            if(u != v && TG[u][v]) 
                ans = max(ans, dp(v) + size[u]);
        return ans;
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            for(int i=0; i<n; i++)
                G[i].clear();
    
            for(int i=0; i<m; i++)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                u--;
                v--;
                G[u].push_back(v);
            }
    
            find_scc(n);
    
            memset(size,0,sizeof(size));
            memset(TG,0,sizeof(TG));
    
            for(int i=0; i<n; i++)
            {
                size[sccno[i]] ++;
                for(int j=0; j<G[i].size(); j++)
                {
                    TG[sccno[i]][sccno[G[i][j]]] = 1;
                }
            }
            int ans = 0;
            memset(d,-1,sizeof(d));
            for(int i=1; i<=scc_cnt; i++)
                ans = max(ans,dp(i));
    
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    Android AHandle AMessage
    android java 与C 通过 JNI双向通信
    android 系统给应用的jar
    UE4 unreliable 同步问题
    UE4 difference between servertravel and openlevel(多人游戏的关卡切换)
    UE4 Run On owing Client解析(RPC测试)
    UE4 TSubclassOf VS Native Pointer
    UE4 内容示例网络同步Learn
    UE4 多人FPS VR游戏制作笔记
    UE4 分层材质 Layerd Materials
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6078965.html
Copyright © 2011-2022 走看看