Uva--11324--The Largest Clique【有向图强连通分量】
题意:一个有向图。找一个最大的点集使得随意两点u、v间都存在一条路(单向或双向),问这个点集最大是多少
思路:强连通分量缩点后得到SCC图,使SCC结点的权等于它的节点个数。找一条路径使得权值和最大就可以。找路径用dp记忆化搜索
#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 1010
#define eps 1e-7
#define INF 0x3F3F3F3F //0x7FFFFFFF
#define LLINF 0x7FFFFFFFFFFFFFFF
#define seed 1313131
#define MOD 1000000007
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 const int maxm = 50010;
struct node{
int u, v, next;
}edge[maxm], edge1[maxm];
int Stack[MAXN];
int head[MAXN], head1[MAXN], dfn[MAXN], low[MAXN], sccno[MAXN], scc_elem[MAXN];
int scc_cnt, id, cnt, cnt1, top, n, m;
int dp[MAXN];
void add_edge(int u, int v, node edge[], int head[], int &cnt){
edge[cnt].u = u;
edge[cnt].v = v;
edge[cnt].next = head[u];
head[u] = cnt++;
}
void tarjin(int u){
int i, j;
dfn[u] = low[u] = ++id;
Stack[top++] = u;
for(i = head[u]; i != -1; i = edge[i].next){
int v = edge[i].v;
if(dfn[v] == -1){
tarjin(v);
low[u] = min(low[u], low[v]);
}
else if(!sccno[v]){
low[u] = min(low[u], dfn[v]);
}
}
if(low[u] == dfn[u]){
scc_cnt++;
int temp;
do{
temp = Stack[--top];
sccno[temp] = scc_cnt;
}while(temp != u);
}
}
int dfs_DAG(int u){
if(dp[u] > 0) return dp[u];
dp[u] = scc_elem[u];
for(int i = head1[u]; i != -1; i = edge1[i].next){
int v = edge1[i].v;
dp[u] = max(dp[u], scc_elem[u] + dfs_DAG(v));
}
return dp[u];
}
int main(){
int i, j, t;
scanf("%d", &t);
while(t--){
scanf("%d%d", &n, &m);
cnt = cnt1 = scc_cnt = id = top = 0;
memset(head, -1, sizeof(head));
memset(head1, -1, sizeof(head1));
memset(dfn, -1, sizeof(dfn));
memset(sccno, 0, sizeof(sccno));
memset(scc_elem, 0, sizeof(scc_elem));
for(i = 0; i < m; i++){
int u, v;
scanf("%d%d", &u, &v);
add_edge(u, v, edge, head, cnt);
}
for(i = 1; i <= n; i++){
if(dfn[i] == -1) tarjin(i);
}
for(i = 1; i <= n; i++){
int x = sccno[i];
scc_elem[x]++;
}
for(i = 0; i < cnt; i++){
int u = edge[i].u;
int v = edge[i].v;
if(sccno[u] != sccno[v]){
add_edge(sccno[u], sccno[v], edge1, head1, cnt1);
}
}
memset(dp, 0, sizeof(dp));
int ans = 0;
for(i = 1; i <= scc_cnt; i++){
ans = max(ans, dfs_DAG(i));
}
printf("%d\n", ans);
}
return 0;
}
Uva--11324--The Largest Clique【有向图强连通分量】的更多相关文章
- UVA 11324 - The Largest Clique(强连通分量+缩点)
UVA 11324 - The Largest Clique 题目链接 题意:给定一个有向图,要求找一个集合,使得集合内随意两点(u, v)要么u能到v,要么v能到u,问最大能选几个点 思路:强连通分 ...
- UVA 11324 The Largest Clique (强连通分量,dp)
给出一个有向图,求一个最大的结点集合,任意两个点u,v.u可到达v或v可到达u. 一个强连通分量肯定一起选的.而且只能在一条路径上. 所以先找出所有scc,然后缩点找一条最大权的路径,按拓扑序跑DAG ...
- Uva 11324 The Largest Clique【强连通 DAG动规 spfa】
白书上的例题 做一遍tarjan后,缩点,每一个scc节点的权为它的结点数,做一次DAG上的动规,求出路径上的最大点权和,就可以了 #include<cstdio> #include< ...
- uva 11324 The Largest Clique(强连通分量缩点+DAG动态规划)
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=25&page=sh ...
- UVA 11324 The Largest Clique(强连通分量+缩点DAG的DP)
题意:给定一个有向图,求出一个最大的结点集,这个节点集中的随意两个点之间至少一个能到达还有一个点. 思路:假设一个点在这个节点集中,那么它所在的强连通分量中的点一定所有在这个节点集中,反之亦然, 求出 ...
- UVa 11324 The Largest Clique (强连通分量+DP)
题意:给定一个有向图,求一个最大的结点集,使得任意两个结点,要么 u 能到 v,要么 v 到u. 析:首先,如果是同一个连通分量,那么要么全选,要么全不选,然后我们就可以先把强连通分量先求出来,然后缩 ...
- UVA - 11324 The Largest Clique 强连通缩点+记忆化dp
题目要求一个最大的弱联通图. 首先对于原图进行强连通缩点,得到新图,这个新图呈链状,类似树结构. 对新图进行记忆化dp,求一条权值最长的链,每一个点的权值就是当前强连通分量点的个数. /* Tarja ...
- UVA - 11324 The Largest Clique (强连通缩点+dp)
题目链接 题意:从有向图G中找到一个最大的点集,使得该点集中任意两个结点u,v满足u可达v或v可达u. 解法:先把同处于一个强连通分量中的结点合并(缩点),得到一张DAG图,在DAG上dp即可. 感觉 ...
- uva 11324 The Largest Clique(图论-tarjan,动态规划)
Problem B: The Largest Clique Given a directed graph G, consider the following transformation. First ...
- uva 11324 The Largest Clique
vjudge 上题目链接:uva 11324 scc + dp,根据大白书上的思路:" 同一个强连通分量中的点要么都选,要么不选.把强连通分量收缩点后得到SCC图,让每个SCC结点的权等于它 ...
随机推荐
- Reading and writing RData files
前面添加个lapply()或者dplyr::llply()就能读取,储存多个文件了.http://bluemountaincapital.github.io/FSharpRProvider/readi ...
- Linux修复系统命令
fsck.ext2(file system check-second filesystem ) 功能说明:检查文件系统并尝试修复错误. 语法:fsck.ext2 [-acdfFnprsStvVy][- ...
- vmrun命令
VMWare提供了vmrun与VIX API两种手段使用户可以通过程序对虚拟机进行控制. 在官方文档中给出了详细的说明和示例代码. vmrun:http://www.vmware. ...
- 实验一 ASP.NET应用环境配置 总结
通过本次实验我学会了在Windows XP系统中安装IIS服务器,虽然我的电脑是Windows7系统,但是通过虚拟机软件,配置了一台Windows XP系统的虚拟机,在虚拟机内进行各项配置操作.这次实 ...
- selenium+java+chrome环境搭建
我只能说因为版本冲突,简直太折腾了,而搜了无数个博友的帖子才找到正确条案,就不能好好的写篇文章吗? 最近真的是太闲太闲了,平时没事总得搞点技术,不然心里感觉好空虚, 最近看上了selenium,所以试 ...
- soapui-使用groovy脚本执行用例请求
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext CURRENT_TESTCASE = testRunner.testCa ...
- 原创:《Excel在零售及电商行业数据化管理中的应用》之“什么是数据化管理?
<Excel在零售及电商行业数据化管理中的应用>之“什么是数据化管理?” 各位: “随着全零售时代的到来,传统商业的每一个供应链细节都离不开数据的支 ...
- 用Python中的tkinter模块作图(续)
八.显示文字 用create_text在画布上写字.这个函数只需要两个坐标(文字x和y的位置),还有一个具名参数来接受要显示的文字.例如: >>> from tkinter impo ...
- Java如何格式化月份?
在Java中,如何以MMMM格式格式化时间? 这个示例使用SimpleDateFormat('MMMM')构造函数和SimpleDateFormat类的sdf.format(date)方法来格式化月份 ...
- JDBC简单示例代码
本文章教程中将演示如何创建一个简单的JDBC应用程序的示例. 这将显示如何打开数据库连接,执行SQL查询并显示结果. 这个示例代码中涉及所有步骤,一些步骤将在本教程的后续章节中进行说明. 创建JDBC ...