UVA 11324 The Largest Clique 强连通缩点+DP
2014-10-09 20:00
344 查看
Problem B: The Largest Clique
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 betweenu and v in G that follows the directed edges only in the forward direction. This graph T(G) is often called thetransitive 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.
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.
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
Output for sample input
4
Zachary Friggsta
先把强连通分量缩点后得到scc图,每个scc节点的权等于他的节点数,因为scc是dag图,所以可以用dp求解
#include <cstdlib> #include <cctype> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <string> #include <iostream> #include <map> #include <set> #include <queue> #include <stack> #include <bitset> using namespace std; #define PB push_back #define MP make_pair #define REP(i,n) for(int i=0;i<(n);++i) #define FOR(i,l,h) for(int i=(l);i<=(h);++i) #define DWN(i,h,l) for(int i=(h);i>=(l);--i) #define CLR(vis,pos) memset(vis,pos,sizeof(vis)) #define PI acos(-1.0) #define INF 0x3f3f3f3f #define LINF 1000000000000000000LL #define eps 1e-8 const int maxn=1234; const int maxm=55555; struct node{ int to,next; }e[maxm]; int head[maxn],edge; int low[maxn],dfn[maxn],stk[maxn],belong[maxn]; int tsp,top; int scc; bool in_stk[maxn]; int num[maxn]; void init(){ edge=0; CLR(head,-1); } void addedge(int u,int v){ e[edge].to=v; e[edge].next=head[u]; head[u]=edge++; } void tarjan(int u){ int v; low[u]=dfn[u]=++tsp; stk[top++]=u; in_stk[u]=true; for(int i=head[u];~i;i=e[i].next){ v=e[i].to; if(!dfn[v]){ tarjan(v); if(low[u]>low[v]) low[u]=low[v]; } else{ if(in_stk[v] && low[u]>dfn[v]) low[u]=dfn[v]; } } if(low[u]==dfn[u]){ scc++; do{ v=stk[--top]; in_stk[v]=false; belong[v]=scc; num[scc]++; }while(v!=u); } } void solve(int N){ CLR(dfn,0); CLR(in_stk,false); CLR(num,0); tsp=top=scc=0; FOR(i,1,N) if(!dfn[i]) tarjan(i); } vector<int> g[maxn]; int dp[maxn]; int dfs(int u){ if(dp[u]) return dp[u]; if(g[u].size()==0) return dp[u]=num[u]; int tmp=0; REP(i,g[u].size()) tmp=max(tmp,dfs(g[u][i])); return dp[u]=tmp+num[u]; } int main() { int _; cin>>_; int n,m; REP(cas,_){ init(); cin>>n>>m; int u,v; REP(i,m){ scanf("%d%d",&u,&v); if(u==v) continue; addedge(u,v); } solve(n); FOR(i,0,n) g[i].clear(); FOR(u,1,n){ for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].to; if(belong[u]!=belong[v]) g[belong[u]].PB(belong[v]); } } int ans=0; CLR(dp,0); FOR(i,1,scc) ans=max(ans,dfs(i)); cout<<ans<<endl; } return 0; }
相关文章推荐
- 【UVa】11324 The Largest Clique 强连通缩点+DP
- UVA-11324 The Largest Clique (强连通+DP)
- UVa11324 The Largest Clique(强连通分量+缩点+记忆化搜索)
- UVA 11324 The Largest Clique(tarjan有向图强连通+缩点)
- uva 11324 The Largest Clique
- Uva 11324 The Largest Clique【强连通 DAG动规 spfa】
- Uva 11324 The Largest Clique
- UVA 11324 The Largest Clique(强连通+dp)
- Uva-11324 The Largest Clique(强连通分量缩点+DAGdp)
- UVa 11324 The Largest Clique / 强连通分量
- UVA11324-- The Largest Clique(SCC+DP)
- uva 11324 - The Largest Clique(缩点 + dp)
- UVA 11324 The Largest Clique(tarjan有向图强连通+缩点)
- uva 11324 The Largest Clique (Tarjan+记忆化)
- UVA 11324 The Largest Clique(SCC+dp)
- UVA 11324 The Largest Clique
- UVA -- 11324 The Largest Clique(强连通+记忆化搜索)
- UVA 11324 The Largest Clique
- UVA - 11324 The Largest Clique
- UVA11324 The Largest Clique