题意:给一个有向图,要求找出一些点,使得这些点中的任意点对,要么可以互通,要么单向可达。

思路:最低只要求单向可达即可,即a->b都可以算进去。

  强连通分量内的点肯定是满足要求的,可以全选,但是有多个强连通分量时就不行了,得有取舍。老方法,先缩点,缩完点后是没有环的存在的,所以就是拓扑图了。如果只给一个拓扑图,要求找一条链使得链上的点最多,那么可以用判断拓扑的方式,逐个将入度为0的点删除,且在删除的时候记录下最多有多少个点,删到最后一个点时就出结果了。这样的方法同样适用,只是每个点可能是缩点,而且要将这些缩点内的点数算上去而已。

实现:

  (1)求强连通分量。

  (2)统计缩点的度数并建(缩点)图。

  (3)按判断拓扑图的方式来进行点数的统计。

 #include <bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
using namespace std;
const int N=+;
const int INF=0x7f7f7f7f;
vector<int> vect[N], g[N]; //原图,缩点后的图
int n, m;
int dfn[N], lowlink[N], scc_no[N], dfn_clock, scc_cnt; //强连通分量必备
stack<int> stac; //强联通分量用栈
unordered_map<int,int> chu[N],ru[N]; //仅仅为了防止重复统计
int r[N]; //出入度
int num[N]; //强联通分量中的点数
int dp[N]; //答案 void DFS(int x)
{
stac.push(x);
dfn[x]=lowlink[x]=++dfn_clock;
for(int i=; i<vect[x].size(); i++)
{
int t=vect[x][i];
if(!dfn[t])
{
DFS(t);
lowlink[x]=min(lowlink[x],lowlink[t]);
}
else if(!scc_no[t]) lowlink[x]=min(lowlink[x], dfn[t]);
}
if(lowlink[x]==dfn[x])
{
++scc_cnt;
while(true)
{
int t=stac.top();stac.pop();
scc_no[t]=scc_cnt;
if(t==x) break;
}
}
} int cal()
{
memset(dfn,,sizeof(dfn));
memset(lowlink,,sizeof(lowlink));
memset(scc_no,,sizeof(scc_no));
dfn_clock=scc_cnt=;
for(int i=; i<=n; i++) if(!dfn[i]) DFS(i); if(scc_cnt==) return n;
for(int i=; i<=scc_cnt; i++) g[i].clear(),chu[i].clear(),ru[i].clear();
for(int i=; i<=n; i++) //统计度,建图
{
for(int j=; j<vect[i].size(); j++)
{
int t=vect[i][j];
if(scc_no[i]!=scc_no[t])
{
if(!chu[scc_no[i]][scc_no[t]]) //还没出现过
{
chu[scc_no[i]][scc_no[t]]=;
g[scc_no[i]].push_back(scc_no[t]);
}
ru[scc_no[t]][scc_no[i]]=;
}
}
}
deque<int> que;
memset(r,,sizeof(r));
for(int i=; i<=scc_cnt; i++) //统计出入度
{
r[i]=ru[i].size();
if(!r[i]) que.push_back(i);
} memset(num,,sizeof(num));
for(int i=; i<=n; i++) num[scc_no[i]]++; //统计点数 memset(dp,,sizeof(dp)); //按拓扑序来dp
int ans=;
while(!que.empty())
{
int siz=que.size();
for(int i=; i<siz; i++) //所有入度为0的节点
{
int t=que.front();que.pop_front();
ans=max(ans,dp[t]+num[t]);
for(int j=; j<g[t].size(); j++) //每条以t出发的边
{
int d=g[t][j];
r[d]--;
if(!r[d]) que.push_back(d);
dp[d]=max(dp[d],dp[t]+num[t]);
}
}
}
return ans;
} int main()
{
//freopen("input.txt", "r", stdin); int t, a, b;
cin>>t;
while(t--)
{
scanf("%d%d", &n, &m);
for(int i=; i<=n; i++) vect[i].clear();
for(int i=; i<m; i++)
{
scanf("%d%d",&a,&b);
vect[a].push_back(b);
}
cout<<cal()<<endl;
}
return ;
}

AC代码

UVA 1324 The Largest Clique 最大团(强连通分量,变形)的更多相关文章

  1. Uva--11324--The Largest Clique【有向图强连通分量】

    链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&am ...

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

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

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

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

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

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

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

    题意:给定一个有向图,求出一个最大的结点集,这个节点集中的随意两个点之间至少一个能到达还有一个点. 思路:假设一个点在这个节点集中,那么它所在的强连通分量中的点一定所有在这个节点集中,反之亦然, 求出 ...

  6. UVa 11324 The Largest Clique (强连通分量+DP)

    题意:给定一个有向图,求一个最大的结点集,使得任意两个结点,要么 u 能到 v,要么 v 到u. 析:首先,如果是同一个连通分量,那么要么全选,要么全不选,然后我们就可以先把强连通分量先求出来,然后缩 ...

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

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

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

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

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

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

随机推荐

  1. Django1.6添加comments应用的简单过程

    今天尝试为自己开发的博客加上评论功能,查看Django的文档,发现1.6之后Django不再自带comments这个app了,下面是官方文档上的说明: Django’s comment framewo ...

  2. 【原创】一起学C++ 之->(箭头符号) ---------C++ primer plus(第6版)

    1.C++新手在指定结构成员时,不知道何时用.运算符,何时是用->运算符. 结论:如果结构标识符是结构名,则使用句点运算符:如果标识符是指向结构的指针,则使用箭头运算符. #include &l ...

  3. (转)《深入理解java虚拟机》学习笔记2——Java内存溢出实例

    通过简单的小例子程序,演示java虚拟机各部分内存溢出情况: (1).java堆溢出: Java堆用于存储实例对象,只要不断创建对象,并且保证GC Roots到对象之间有引用的可达,避免垃圾收集器回收 ...

  4. django开发框架-view & template

    django框架的主要模型是MVT,Model模型,View视图,Template模板,基于基本的HttpRequest方式. django支持的数据库有四种:PostgreSQL,MySQL, Or ...

  5. 微软职位内部推荐-Principal Dev Manager for Windows Phone Apps

    微软近期Open的职位: Location: China, BeijingDivision: Operations System Group Engineering Group OverviewOSG ...

  6. 为什么要用Hibernate框架? 把SessionFactory,Session,Transcational封装成包含crud的工具类并且处理了事务,那不是用不着spring了?

    既然用Hibernate框架访问管理持久层,那为何又提到用Spring来管理以及整合Hibernate呢?把SessionFactory,Session,Transcational封装成包含crud的 ...

  7. python学习笔记12(函数三): 参数类型、递归、lambda函数

    一.函数参数的类型 之前我们接触到的那种函数参数定义和传递方式叫做位置参数,即参数是通过位置进行匹配的,从左到右,依次进行匹配,这个对参数的位置和个数都有严格的要求.而在Python中还有一种是通过参 ...

  8. linux驱动系列之tftp(转)

    转自网页:http://blog.csdn.net/xingyu19871124/article/details/7315893 最近在将做的嵌入式项目移植到ARM开发板上,宿主机用的ubuntu11 ...

  9. unity手游之聊天SDK集成与使用一

    手游中都有聊天功能,比如公会,私聊,世界聊天,那么找一个好用,功能强大的SDK的可以节省很多精力,帮助我们提高开发速度与游戏质量. 写本篇博文是为了方便使用这个SDK做聊天模块的程序,避免许多坑,我在 ...

  10. 使用Pod集成Bugtags填坑记

    最近某朋友的朋友的创业公司新出了一个工具叫Bugtags,说是可以让APP测试变得so easy,于是动手来做1.1.0的版本集成,先把WEB首页贴在下面,感兴趣的同学可以去look一下:https: ...