题目链接:https://vjudge.net/problem/UVA-11324

题意:求一个有向图中结点数最大的结点集,使得该结点集中任意两个结点u和v满足:要目u可以到达v,要么v可以到达u(相互可达也可以)。

思路:同一个强联通分量的结点集中任意两个结点u和v满足题的要求足:要么u可以到达v,要么v可以到达u(相互可达也可以)。把强联通分量收缩点后得到scc图,让每个scc结点的权值等于他的结点数,则求scc图上权最大的路径。拓扑dp,也可以直接bfs,但是要建立一个新的起点,连接所有入度为0的结点。

代码:

#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<vector>
using namespace std;
typedef long long ll;
const int MAXN=2e5+,INF=0x3f3f3f3f,MOD=1e9+;
map<int,vector<int> >G;
int pre[MAXN],lowlink[MAXN],sccno[MAXN],dfs_color,scc_cut;
stack<int>S;
map<int,vector<int> >NG;
int deg[MAXN];
int in[MAXN];
void dfs(int u)
{
pre[u]=lowlink[u]=++dfs_color;
S.push(u);
for(int i=; 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],lowlink[v]);
}
if(lowlink[u]==pre[u])
{
scc_cut++;
while(!S.empty())
{
int x=S.top();
S.pop();
sccno[x]=scc_cut;
deg[scc_cut]++;
if(x==u) break;
}
}
}
void find_scc(int n)
{
dfs_color=scc_cut=;
memset(pre,,sizeof(pre));
memset(sccno,,sizeof(sccno));
memset(deg,,sizeof(deg));
for(int i=; i<=n; i++)
if(!pre[i]) dfs(i);
}
void re_build(int n)
{
for(int i=; i<=scc_cut; i++) in[i]=,NG[i].clear();
for(int u=; u<=n; u++)
{
for(int i=; i<G[u].size(); i++)
{
int v=G[u][i];
if(sccno[u]==sccno[v]) continue;
in[sccno[v]]++;
NG[sccno[u]].push_back(sccno[v]);
}
}
for(int i=; i<=n; i++) G[i].clear();
}
queue<int>q;
int ans[MAXN];
void topsort()
{
memset(ans,,sizeof(ans));
for(int i=; i<=scc_cut; i++)
if(in[i]==) ans[i]=deg[i],q.push(i);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=; i<NG[u].size(); i++)
{
int v=NG[u][i];
ans[v]=max(ans[v],ans[u]+deg[v]);
in[v]--;
if(in[v]==) q.push(v);
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=; i<=m; i++)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
}
find_scc(n);
re_build(n);
topsort();
int Max=;
for(int i=; i<=scc_cut; i++)
Max=max(Max,ans[i]);
cout<<Max<<endl;
}
return ;
}

tarjan缩点+拓扑dp

UVA 11324.The Largest Clique tarjan缩点+拓扑dp的更多相关文章

  1. UVA - 11324 The Largest Clique 强连通缩点+记忆化dp

    题目要求一个最大的弱联通图. 首先对于原图进行强连通缩点,得到新图,这个新图呈链状,类似树结构. 对新图进行记忆化dp,求一条权值最长的链,每一个点的权值就是当前强连通分量点的个数. /* Tarja ...

  2. UVA 11324 The Largest Clique(缩点+DAG上的dp)

    求最大团.和等价性证明有类似之处,只不过这个不是求互推,而是只要a->b,或b->a即可. 同样的,容易想到先缩点,得到DAG,每个节点上保存SCC的点数,相信任意一条由根节点(入度为零) ...

  3. UVA - 11324 The Largest Clique (强连通缩点+dp)

    题目链接 题意:从有向图G中找到一个最大的点集,使得该点集中任意两个结点u,v满足u可达v或v可达u. 解法:先把同处于一个强连通分量中的结点合并(缩点),得到一张DAG图,在DAG上dp即可. 感觉 ...

  4. UVA 11324 The Largest Clique (强连通分量,dp)

    给出一个有向图,求一个最大的结点集合,任意两个点u,v.u可到达v或v可到达u. 一个强连通分量肯定一起选的.而且只能在一条路径上. 所以先找出所有scc,然后缩点找一条最大权的路径,按拓扑序跑DAG ...

  5. UVA 11324 - The Largest Clique(强连通分量+缩点)

    UVA 11324 - The Largest Clique 题目链接 题意:给定一个有向图,要求找一个集合,使得集合内随意两点(u, v)要么u能到v,要么v能到u,问最大能选几个点 思路:强连通分 ...

  6. uva 11324 The Largest Clique(图论-tarjan,动态规划)

    Problem B: The Largest Clique Given a directed graph G, consider the following transformation. First ...

  7. uva 11324 The Largest Clique

    vjudge 上题目链接:uva 11324 scc + dp,根据大白书上的思路:" 同一个强连通分量中的点要么都选,要么不选.把强连通分量收缩点后得到SCC图,让每个SCC结点的权等于它 ...

  8. uva 11324 The Largest Clique(强连通分量缩点+DAG动态规划)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=25&page=sh ...

  9. uva 11324 The Largest Clique (Tarjan+记忆化)

    /*每个环 要么不选 要么全选 可缩点 就得到一个GAD图 然后搞搞算出最大路径*/ #include<iostream> #include<cstdio> #include& ...

随机推荐

  1. Linux简介及Linux学习路线图

    一.Linux 为何物 Linux 就是一个操作系统,就像你多少已经了解的 Windows(xp,7,8)和 Max OS ,至于操作系统是什么,就不用过多解释了,如果你学习过前面的入门课程,应该会有 ...

  2. linux 内核启动流程

    Linux内核启动流程详细分析: http://www.linuxidc.com/Linux/2014-10/108034.htm ARM Linux内核启动过程: http://blog.csdn. ...

  3. Spread Syntax

    [Spread Syntax] The spread syntax allows an expression to be expanded in places where multiple argum ...

  4. metasploit framework(八):snmp扫描,暴力破解

    snmp扫描linux 设置相关参数,这里使用的默认字典,你可以自己制定字典. run 然后使用枚举模块 设置相关参数 run,详细的信息就枚举出来了 snmp扫描windows 先枚举用户 设置目标 ...

  5. struts2前后台传值的三种方法

    原文地址: http://laokaddk.blog.51cto.com/368606/1340816 多的不说,直接上代码; struts.xml代码: <?xml version=" ...

  6. leetcode 数组类型题总结

    1,removeDuplicates(I) int removeDuplicatesI(vector<int>& nums){ // 重新组织数组,同 removeDuplicat ...

  7. Linux 机器的渗透测试命令备忘表

    如下是一份 Linux 机器的渗透测试备忘录,是在后期开发期间或者执行命令注入等操作时的一些典型命令,设计为测试人员进行本地枚举检查之用. 系统信息命令 对于本地的枚举检查很有用. 基于 Redhat ...

  8. 跳台阶(python)

    题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). # -*- coding:utf-8 -*- class Soluti ...

  9. poj3104(二分)

    题目链接:http://poj.org/problem?id=3104 题意:有n件衣服,每一件含有a[i]单位的水,每分钟衣服可以自然蒸发1单位的水,也可以在烘干器上每分钟烘干k单位的水,问将所有衣 ...

  10. 牛客网练习赛12---A and B

    A题传送门:https://www.nowcoder.net/acm/contest/68/A B题传送门:   https://www.nowcoder.net/acm/contest/68/B A ...