UVA11324_The Largest Clique_tarjan求强连通分量+DP求最长路
2013-07-21 22:19
369 查看
题意:
给一个图,求它的一个最大子图,使得图中任意两点之间都至少有一条路径【注意是两点之间有路径,而不是可以到达任意一点,所以不是强连通分量】
【PS:题中给的传递闭包其实是个迷惑,没有用,因为在原图上做,和在传递闭包的图上做是完全一样的】
题解:
先求出图中的所有强连通分量,将每个分量缩为一点使之成为一个DAG图,这样在这个无环图中,找子图使得满足条件
关键:
把问题“使得子图中任意两点之间都至少有一条路径”转化成“求一条最长路径”
这个非常关键,反正我刚开始挺难想的,不过推一推确实是这样,由于任意两点之间都有路,所以所有的路都可以压缩到同一条路径上,如果不能压缩,说明这个子图一定存在两点之间没有有向路径
而求最长路的问题又可以用DP来做,状态转移方程为 dp[u]=val[u]+max(dp[v])
其中,v是u的全部子节点,val[u]为当前标号为u的强连通分量中的结点个数,这样就可以求出来最大子图了
原题:
u and v in G that follows the directed edges only in the forwarddirection. 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 thatfor any two vertices u and v in U, there is a directededge 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 integersn and m, where 0 ≤ n ≤ 1000 is the number ofvertices of Gand 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 vbetween 1 and n which definea 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).
代码:
给一个图,求它的一个最大子图,使得图中任意两点之间都至少有一条路径【注意是两点之间有路径,而不是可以到达任意一点,所以不是强连通分量】
【PS:题中给的传递闭包其实是个迷惑,没有用,因为在原图上做,和在传递闭包的图上做是完全一样的】
题解:
先求出图中的所有强连通分量,将每个分量缩为一点使之成为一个DAG图,这样在这个无环图中,找子图使得满足条件
关键:
把问题“使得子图中任意两点之间都至少有一条路径”转化成“求一条最长路径”
这个非常关键,反正我刚开始挺难想的,不过推一推确实是这样,由于任意两点之间都有路,所以所有的路都可以压缩到同一条路径上,如果不能压缩,说明这个子图一定存在两点之间没有有向路径
而求最长路的问题又可以用DP来做,状态转移方程为 dp[u]=val[u]+max(dp[v])
其中,v是u的全部子节点,val[u]为当前标号为u的强连通分量中的结点个数,这样就可以求出来最大子图了
原题:
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 as G. Create a directed edge betweentwo vertices u and v in T(G) if and only if there is a pathbetweenu and v in G that follows the directed edges only in the forwarddirection. 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 thatfor any two vertices u and v in U, there is a directededge 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 integersn and m, where 0 ≤ n ≤ 1000 is the number ofvertices of Gand 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 vbetween 1 and n which definea 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 41 5 2
Output for sample input
4
代码:
RunID | User | Problem | Result | Memory | Time | Language | Length | Submit Time |
---|---|---|---|---|---|---|---|---|
1321499 | chengtbf | A | Accepted | 0 KB | 152 ms | C++ 4.5.3 | 2550 B | 2013-07-21 21:58:40 |
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<stack> #define N 1005 #define M 50005 using namespace std; int dfs_time; int dfn ,low ; int color ; int dfs_color; int n,m; struct MyStruct { int u,v; }edge[M]; vector<int>f ; vector<int>DAG ;//存缩点后的图 stack<int>sta; int visited ; int in_stack ;//判断是否在栈中 int dp ; int val ;//即每个强连通分量中的结点个数 int vis_DAG ;//标记DAG图中的缩点有没有被访问过 int find_min(int a,int b) { return a<b?a:b; } void tarjan(int u) { dfn[u]=low[u]=++dfs_time; visited[u]=1; sta.push(u); in_stack[u]=1; int child; for (int i = 0; i <f[u].size() ; i++) { child=f[u][i]; if (!visited[child]) { tarjan(child); low[u]=find_min(low[u],low[child]); } else if(in_stack[child]) { low[u]=find_min(low[u],dfn[child]); } } if (dfn[u]==low[u])//说明u是当前连通分量的根 { dfs_color++; do//弹出当前强连通分量 { child=sta.top(); color[child]=dfs_color; sta.pop(); in_stack[child]=0; val[dfs_color]++; } while (u!=child); } } void dp_DAG(int u)//这里的u是强连通分量的缩点的标号 { vis_DAG[u]=1; int max=0; int child; for (int i = 0; i < DAG[u].size(); i++) { child=DAG[u][i]; if (!vis_DAG[child]) { dp_DAG(child); } if (max<dp[child]) { max=dp[child]; } } dp[u]=val[u]+max;//如果dfs搜到叶子结点,就直接到这一步,此时max=0,恰好满足dp[u]=val[u] } int main() { int i,j,a,b,t; int point_u,point_v; int ans; scanf("%d",&t); while (t--) { scanf("%d%d",&n,&m); for ( i = 0; i <=n ; i++) { f[i].clear(); DAG[i].clear(); } if (!sta.empty()) { sta.pop(); } memset(visited,0,sizeof(visited)); memset(val,0,sizeof(val)); memset(in_stack,0,sizeof(in_stack)); memset(dp,0,sizeof(dp)); memset(vis_DAG,0,sizeof(vis_DAG)); dfs_time=0; dfs_color=0; ans=0; for ( i = 1; i <=m ; i++)//输入,存边,存图 { scanf("%d%d",&a,&b); edge[i].u=a; edge[i].v=b; f[a].push_back(b); } for ( i = 1; i <=n ; i++)//求强连通分量 { if (!visited[i]) { tarjan(i); } } for ( i = 1; i <=m ; i++)//存DAG图 { point_u=color[edge[i].u]; point_v=color[edge[i].v]; DAG[point_u].push_back(point_v); } for ( i = 1; i <=dfs_color ; i++) { if (!vis_DAG[i]) { dp_DAG(i); } } for ( i = 1; i <=dfs_color; i++) { if (dp[i]>ans) { ans=dp[i]; } } printf("%d\n",ans); } return 0; }
相关文章推荐
- UVA 11324 The Largest Clique(tarjan有向图强连通+缩点)
- uva 11324 The Largest Clique(图论-tarjan,动态规划)
- Uva11324 The Largest Clique tarjan+dp
- 【Uva11324】The Largest Clique【SCC】【最长路】【有向图最大团】
- UVa11324 The Largest Clique(强连通分量+DP)
- UVa 11324 The Largest Clique (强连通分量+DP)
- UVA 11324 - The Largest Clique(强连通分量+DP)
- uva 11324 The Largest Clique(图论-tarjan,动态规划)
- uva 11324 The Largest Clique (Tarjan+记忆化)
- uva 11324 The Largest Clique(图论-tarjan,动态规划)
- UVA 11324 The Largest Clique(tarjan有向图强连通+缩点)
- UVa 11324 The Largest Clique (强连通分量,dp)
- UVA 11324 - The Largest Clique(SCC缩点 + DP)
- UVA11324_The Largest Clique
- UVA 11324 The Largest Clique(强连通缩点+记忆化搜索)
- UVA 11324 The Largest Clique(SCC+DP)
- UVA 11324 The Largest Clique(缩点+DAG上的dp)
- Uva 11324 The Largest Clique【强连通 DAG动规 spfa】
- UVA 11324 The Largest Clique 强连通缩点+DP
- UVA -- 11324 The Largest Clique(强连通+记忆化搜索)