训练赛 Grouping(强连通分量缩点 + DAG求最长路)
来源:互联网 发布:网络外壳已经停止工作 编辑:程序博客网 时间:2024/05/21 19:45
http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=158#problem/F
大致题意:给出n个人和m种关系(ti,si),表示ti的年龄不小于si。问最小能被划分为几个集合,每个集合都要满足里面的人都无法比较。
思路:对于一条路上的点,它们必定不能被划分到同一个集合中,因此原题变为求一条最长路。而题目中有可能出现环。因此,先tarjan缩点转化为DAG,而缩点后的每个点的点权便是该节点中包含的点的个数,然后记忆化求最长路。
PS:该题与上一篇
uva 11324 The Largest Clique是一样的。该题重在转化。
#include <stdio.h>#include <iostream>#include <algorithm>#include <map>#include <stack>#include <vector>#include <math.h>#include <string.h>#include <queue>#include <string>#include <stdlib.h>#define LL long long#define _LL __int64#define eps 1e-8#define PI acos(-1.0)using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 100010;vector <int> edge[maxn],edge2[maxn];int n,m;int dfn[maxn],low[maxn],instack[maxn],dep,scc;stack <int> st;int set[maxn],num[maxn];int d[maxn];void init(){ for(int i = 1; i <= n; i++) { edge[i].clear(); edge2[i].clear(); } memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(instack,0,sizeof(instack)); while(!st.empty()) st.pop(); dep = 0; scc = 0; memset(num,0,sizeof(num)); memset(d,0,sizeof(d));}void tarjan(int u){ dfn[u] = low[u] = ++dep; instack[u] = 1; st.push(u); for(int i = 0; i < (int)edge[u].size(); i++) { int v = edge[u][i]; if(!dfn[v]) { tarjan(v); low[u] = min(low[u],low[v]); } else if(instack[v]) low[u] = min(low[u],dfn[v]); } if(dfn[u] == low[u]) { scc++; int t; while(1) { t = st.top(); st.pop(); instack[t] = 0; set[t] = scc; num[scc]++; if(t == u) break; } }}void creat(){ for(int u = 1; u <= n; u++) { for(int i = 0; i < (int)edge[u].size(); i++) { int v = edge[u][i]; if(set[u] != set[v]) edge2[set[u]].push_back(set[v]); } }}int dp(int u){ if(d[u]) return d[u]; else if(edge2[u].size() == 0) return d[u] = num[u]; int ans = 0; for(int i = 0; i < (int)edge2[u].size(); i++) { int v = edge2[u][i]; ans = max(ans,dp(v)); } return d[u] = ans+num[u];}int main(){ int u,v; while(~scanf("%d %d",&n,&m)) { init(); for(int i = 1; i <= m; i++) { scanf("%d %d",&u,&v); edge[u].push_back(v); } for(int i = 1; i <= n; i++) if(!dfn[i]) tarjan(i); creat(); int ans = 0; for(int i = 1; i <= scc; i++) { ans = max(ans,dp(i)); } printf("%d\n",ans); } return 0;}
0 0
- 训练赛 Grouping(强连通分量缩点 + DAG求最长路)
- 【APIO2009T3】抢掠计划-强连通分量缩点+DAG单源最长路
- zoj3795 Grouping --- 强连通,求最长路
- ZOJ 3795 Grouping 强连通缩点 + DAG最长路
- BZOJ-1051 受欢迎的牛 Tarjan求强连通分量+缩点DAG
- 【训练题】强连通分量缩点
- Tarjan求强连通分量 缩点
- 强连通分量,DAG上的最长路,记忆化搜索(最大团,UVA 11324)
- 强连通分量缩点
- 强连通分量缩点
- poj 2553 (tarjan求强连通分量+缩点)
- tarjan算法缩点&&求强连通分量【转载】
- POJ 3592 Instantaneous Transference (强连通分量 缩点 spfa最长路)
- BZOJ 1179 ATM (强连通分量缩点+spfa最长路)
- uva 11324 The Largest Clique(强连通分量缩点+DAG动态规划)
- POJ 3114 - Countries in War(强连通分量+缩点+拓扑排序+DAG最短路)
- UVA 11324 The Largest Clique(强连通分量+缩点DAG的DP)
- UVA 11324 有向图强连通分量缩点得SCC图,并在其上求最长路径
- Linux 下 Error: Could not find or load main class Hello
- Fragment+ViewPager+TabPageIndicator使用的时候遇到的问题
- 面向接口编程 java
- ant 使用指南
- 标记-清除算法
- 训练赛 Grouping(强连通分量缩点 + DAG求最长路)
- IOS中获取各个文件的目录路径的方法和NSFileManager类
- 欧拉函数
- jdbc连接SQL Server——非常简单,只需3步
- 读mybatis源码之十四:mybatis事务处理
- dojo小例子(17)iframe上传文件到rest后台,以及乱码问题解决
- struts关于多个时间需要转换
- 程序员技术练级攻略
- C语言几点说明