UVa11324 最大团 The Largest Clique-有向图强连通分量&DP

https://vjudge.net/problem/UVA-11324

给定一张有向图G,求一个节点数目最大的节点集,使得该集合中的任意两个节点u和v满足:要么u可以到达v,要么v可以到达u(u,v相互可达也算满足),要求输出最大的节点数

Given a directed graph G, consider the following transformation. First, create a new graph T(G) to have the same vertex set as G. Create a directed edge between two vertices u and v in T(G) if and only if there is a path between u and v in G that follows the directed edges only in the forward direction. This graph T(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 vertices u 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.

Input The number of cases is given on the first line of input. Each test case describes a graph G. It begins with a line of two integers n and m, where 0 ≤ n ≤ 1000 is the number of vertices of G and 0 ≤ m ≤ 50, 000 is the number of directed edges of G. The vertices of G are numbered from 1 to n. The following m lines contain two distinct integers u and v between 1 and n which define a directed edge from u to v in G.

Output For each test case, output a single integer that is the size of the largest clique in T(G).

Sample Input 1 5 5 1 2 2 3 3 1 4 1 5 2

Sample Output 4

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<vector>
 4 #include<cstring>
 5 using namespace std;
 6 const int maxn=1010;
 7 struct Edge{
 8     int go,next;
 9 };
10 struct InputEdge{
11     int from,to;
12 };
13 int T,a,b,n,m,book[maxn],bcc_count,v[maxn],end[maxn],end2[maxn],map[maxn][maxn],bcc_node[maxn],mem[maxn];
14 vector<int> G[maxn],G2[maxn];
15 vector<InputEdge> inputedge;
16 vector<int> S;
17 void init(){
18     memset(v,0,sizeof(v));
19     memset(book,0,sizeof(book));
20     bcc_count=0;
21     //memset(end,0,sizeof(end));
22     //memset(end2,0,sizeof(end2));
23     S.clear();
24     for(int i=1;i<=n;i++){
25         G[i].clear();
26         G2[i].clear();
27     }
28     memset(map,0,sizeof(map));
29     inputedge.clear();
30     memset(bcc_node,0,sizeof(bcc_node));
31     memset(mem,0,sizeof(mem));
32 }
33 void add(int from,int to){
34     //Edge e;e.go=to;e.next=end[from];G.push_back(e);end[from]=G.size()-1;
35     G[from].push_back(to);
36 }
37 void add2(int from,int to){
38     //Edge e;e.go=to;e.next=end2[from];G2.push_back(e);end2[from]=G2.size()-1;
39     G2[from].push_back(to);
40 }
41 void dfs(int u){
42     v[u]=1;
43     for(/*int i=end[u];i;i=G[i].next*/int i=0;i<G[u].size();i++){
44         //int go=G[i].go;
45         int go=G[u][i];
46         if(!v[go]) dfs(go);
47     }
48     S.push_back(u);
49 }
50 void dfs2(int u){
51     book[u]=bcc_count;
52     bcc_node[bcc_count]++;
53     for(/*int i=end2[u];i;i=G2[i].next*/int i=0;i<G2[u].size();i++){
54         //int go=G2[i].go;
55         int go=G2[u][i];
56         if(!book[go]) dfs2(go);
57     }
58 }
59 int dp(int x){
60     if(mem[x]) return mem[x];
61     int& ans=mem[x];
62     for(int i=1;i<=bcc_count;i++) if(i!=x&&map[i][x]) ans=max(ans,dp(i)+bcc_node[x]);
63     if(!ans) ans=bcc_node[x];
64     return ans;
65 }
66 int main()
67 {
68     scanf("%d",&T);
69     while(T--){
70         scanf("%d %d",&n,&m);
71         init();
72         for(int i=1;i<=m;i++){
73             scanf("%d %d",&a,&b);
74             add(a,b);add2(b,a);
75             inputedge.push_back((InputEdge){a,b});
76         }
77         for(int i=1;i<=n;i++) if(!v[i]) dfs(i);
78         for(int i=n-1;i>=0;i--) if(!book[S[i]]){
79             bcc_count++;
80             dfs2(S[i]);
81         }
82         if(bcc_count==1){
83             printf("%d\n",n);
84             continue;
85         }
86         for(int i=0;i<inputedge.size();i++){
87             InputEdge& e=inputedge[i];
88             map[book[e.from]][book[e.to]]=1;
89         }
90         int ans=0;
91         for(int i=1;i<=bcc_count;i++)
92             ans=max(ans,dp(i));
93         printf("%d\n",ans);
94     }
95     return 0;
96 }

用邻接表存图求BCC会出错....

时间: 2024-10-10 20:00:08

UVa11324 最大团 The Largest Clique-有向图强连通分量&DP的相关文章

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

UVA 11324 - The Largest Clique 题目链接 题意:给定一个有向图,要求找一个集合,使得集合内任意两点(u, v)要么u能到v,要么v能到u,问最大能选几个点 思路:强连通分量,构造出scc之后,缩点,每个点的权值是集合点个数,然后做一遍dag找出最大权值路径即可 代码: #include <cstdio> #include <cstring> #include <vector> #include <stack> #include

UVA - 11324 The Largest Clique (DAG + 强连通分量)

题目大意:给出一张有向图G,求一个结点数最大的结点集,使得该点集中任意两个结点u和v满足: 要么u可到达v,要么v可以到达u(u和v互相可达也可以) 解题思路:u和v相互可达的时候,就是两个结点在同一个强连通分量内的时候 首先要保证集合里面的点可达:强连通分量就满足集合内的点都相互可达.所以第一件事就是找出所有的强连通分量,并统计出每个强连通分量内的结点数 然后找出每个强连通分量之间的关系,也就是找出两个强连通分量之间的桥,连接可连接的强连通分量 最后将每个强连通分量收缩,得到SCC图.此时的S

有向图强连通分量

部分转自 [有向图强连通分量] 有向图中,如果一个子图内任意两点都可达这这个子图为强连通子图 如图所示{1, 2,3,4},{5},{6} 为一个强连通子图 求连通分量 1.用Kosaraju算法(PS:个人感觉Kosaraju算法比较好理解,但是适用范围不如Tarjan算法广) 如果在原图中点 i 可达 点 j 如果图逆向之后,i 依然可以达到 j ,这么可以认为 i 和 j 在同一个强连通分量里 具体算法是 1.先对图进行一次DFS进行标号确定逆向图进行搜索的次序,越接近图的尾部(搜索树的叶

【转载】有向图强连通分量的Tarjan算法

from byvoid [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强连通分量,时间复杂度为

算法笔记_144:有向图强连通分量的Tarjan算法(Java)

目录 1 问题描述 2 解决方案 1 问题描述 引用自百度百科: 如果两个顶点可以相互通达,则称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.有向图的极大强连通子图,称为强连通分量(strongly connected components). Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树.搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量. 定义D

有向图强连通分量的Tarjan算法(转)

原文地址:有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强

POJ3180(有向图强连通分量结点数&gt;=2的个数)

The Cow Prom Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1451   Accepted: 922 Description The N (2 <= N <= 10,000) cows are so excited: it's prom night! They are dressed in their finest gowns, complete with corsages and new shoes. T

有向图强连通分量的Tarjan算法——转自BYVoid

[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强连通分量,时间复杂度为O(N^2+M).更好的

有向图强连通分量的Tarjan算法

有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强连通分量,