UVA11324 - The Largest Clique(强连通最大团)
来源:互联网 发布:淘宝怎么买药品 编辑:程序博客网 时间:2024/05/08 18:36
Problem B: The Largest Clique
Given a directed graph G, consider the following transformation. First, create a new graphT(G) to have the same vertex set asG. Create a directed edge between two vertices u and v inT(G) if and only if there is a path between u and v inG that follows the directed edges only in the forward direction. This graphT(G) is often called the transitive closure of G.
We define a clique in a directed graph as a set of vertices U such that for any two verticesu and v in U, there is a directed edge either from u to v or from v to u (or both). The size of a clique is the number of vertices in the clique.
The number of cases is given on the first line of input. Each test case describes a graphG. It begins with a line of two integersn and m, where 0 ≤n ≤ 1000 is the number of vertices of Gand 0 ≤ m ≤ 50,000 is the number of directed edges ofG. The vertices of G are numbered from 1 to n. The followingm lines contain two distinct integers u and vbetween 1 andn which define a directed edge from u to v in G.
For each test case, output a single integer that is the size of the largest clique inT(G).
Sample input
15 51 22 33 14 15 2
Output for sample input
4
题意:给一张有向图G。求一个节点数最大的节点集,使得该节点集中任意两个节点u和v满足:要么u可以到达v,要么v可以到达u(u和v相互可达也可以)
思路:同一个强连通分量中的点要么都选,要么都不选。把强连通分量收缩点后得到SCC图,让每个SCC节点的权等于他的节点数,则题目转化为求SCC图上权最大的路径。可以用记忆化搜索搞。
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>using namespace std;#define maxn 50080#define maxm 200080int first[maxn];int nxt[maxm],vv[maxm];int dfn[maxn],low[maxn],vis[maxn];int S[maxn],c[maxn],sum[maxn];int e,cnt,p,t;int maxsum[maxn];int n,m;void addedge(int u,int v){ vv[e] = v; nxt[e] = first[u]; first[u] = e++;}void init(){ e = cnt = p = t = 0; memset(first,-1,sizeof(first)); memset(dfn,0,sizeof(dfn)); memset(vis,0,sizeof(vis)); memset(sum,0,sizeof(sum)); memset(maxsum,-1,sizeof(maxsum));}void Tarjan(int u){ vis[u] = 1; S[++p] = u; dfn[u] = low[u] = ++cnt; for(int i = first[u];i != -1;i = nxt[i]) { int v = vv[i]; if(!dfn[v]) { Tarjan(v); low[u] = min(low[u],low[v]); } else if(vis[v]) low[u] = min(low[u],dfn[v]); } if(dfn[u] == low[u]) { ++t; while(S[p] != u) { vis[S[p]] = 0; c[S[p]] = t; sum[t]++; p--; } vis[S[p]] = 0; c[S[p]] = t; p--; sum[t]++; }}int dfs(int u){ if(maxsum[u] != -1) return maxsum[u];//如果这个强连通分量已经确定了。 maxsum[u] = sum[u];int add = 0; for(int i = 1;i <= n;i++) { if(c[i] == u)//如果这个点是这个强连通分量的 { for(int j = first[i];j != -1;j = nxt[j]) { int v = vv[j]; int cv = c[v]; if(u == cv) continue; add = max(add,dfs(cv)); } } } maxsum[u] += add; return maxsum[u];}int main(){ //freopen("in.txt","r",stdin); int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); init(); for(int i = 1;i <= m;i++) { int u,v; scanf("%d%d",&u,&v); if(u == v) continue; addedge(u,v); } for(int i = 1;i <= n;i++) if(!dfn[i]) { Tarjan(i); } int ans = 0; for(int i = 1;i <= t;i++) ans = max(ans,dfs(i)); printf("%d\n",ans); } return 0;}
- UVA11324 - The Largest Clique(强连通最大团)
- 【UVa11324】最大团The Largest Clique【强联通分量】【DAG】
- uva11324 The Largest Clique --- 强连通+dp
- UVA11324.The Largest Clique最大团——scc+dp
- UVa11324 The Largest Clique(强连通分量+DP)
- UVA11324 The Largest Clique (强联通 + DP)
- UVA11324 The Largest Clique,有向图,最大团的结点数
- 【Uva11324】The Largest Clique【SCC】【最长路】【有向图最大团】
- UVA11324 The Largest Clique
- uva11324 - The Largest Clique 有向图强连通分量+缩点+DP
- UVA11324 The Largest Clique 强连通分量缩点+有向无环图最大点权和
- Uva 11324 - The Largest Clique 缩点 求最大团
- Uva11324 The Largest Clique tarjan+dp
- UVa11324 - The Largest Clique(DAG+DP+SCC)
- UVA11324-- The Largest Clique(SCC+DP)
- UVA11324 The Largest Clique (强联通+缩点+DAG上DP最长路)
- UVa 11324 The Largest Clique / 强连通分量
- uva 11324 The Largest Clique (强连通分量+dp)
- ios学习--iphone 实现下拉菜单
- asp.net中获取GridView当前行的索引
- 初识云计算day019
- 求100到200之间的素数
- 阶层
- UVA11324 - The Largest Clique(强连通最大团)
- 【Intervals POJ 区间覆盖】
- RMAN备份重建数据库
- TCP/IP参考模型
- 下降迭代算法
- Android NDK编程小试---实现java和c语言的互掉
- 关于产品的一些思考——问一答之背包之编辑题目
- C语言中 i++ 和 ++i 有什么区别?
- 微软面试100题-天天做-第一题