ZOJ 3795 Grouping (强连通缩点+DP最长路)
<题目链接>
题目大意:
n个人,m条关系,每条关系a >= b,说明a,b之间是可比较的,如果还有b >= c,则说明b,c之间,a,c之间都是可以比较的。问至少需要多少个集合使得每个集合内的人都是不可比较的。
解题分析:
将所给的关系当成有向边,根据题意,同一强连通分量中的任意两点不能分到一组,所以我们先将整张图进行缩点,缩点后"点"的中点的数量当做点权,然后就可以转化为最长路的求解了。这里比较难想,因为同一连通分量中的点不能在一组,所以必然要将它们全部排成一条。因为要求最少分成的组,所以我们只需要将整张图的最长关键路径(最大点权和的路径)找出即可,这样可以将不在关键路径上的"点"中的所有的点与最长路径上的不同点分配到一组,因为它们不属于一个连通分量,所以这样分配,每组之间的所有点仍然是不可比较的。又因为这是最长路径,所以每次必然能够最长路径之外的"点"中所有的点与最短路径上的点一 一分配到一组。
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
const int N = 1e5+;
const int M = 3e5+;
struct Edge{
int v, nxt;
} edge[M], edg[M];
int n,m,tott, tot, ord, scc, top;
int cnt[N], dp[N], head[N], hea[N], vis[N], deg[N], dfn[N], low[N], belong[N],stk[N]; void init(){
tot = scc = tott = ord = top = ;
memset(head, -, sizeof(head));
memset(hea, -, sizeof(hea));
memset(dfn, , sizeof(dfn));
memset(dp, , sizeof(dp));
memset(cnt,,sizeof(cnt));
}
void Add(int u, int v) {
edge[tot].v = v; edge[tot].nxt = head[u];
head[u] = tot++;
}
void add(int u, int v) {
edg[tott].v = v; edg[tott].nxt = hea[u];
hea[u] = tott++;
}
void tarjan(int u) {
dfn[u] = low[u] = ++ord;
stk[++top]=u; vis[u] = ;
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}else if(vis[v])low[u]=min(low[u],dfn[v]);
}
if(low[u] == dfn[u]) {
++scc;
while(true){
int v=stk[top--];
belong[v] = scc;
cnt[scc]++;
vis[v] = ;
if(v==u)break;
}
}
}
//将"点"中点的数量作为这个点的点权,然后求出最大点权的路径
//dp[u]表示,以u为起点的最长路径
int DFS(int u) {
if(dp[u]) return dp[u];
int ans = cnt[u];
for(int i = hea[u]; ~i; i = edg[i].nxt) {
int v = edg[i].v;
ans = max(ans, DFS(v) + cnt[u]);
}
return dp[u] = ans;
}
int main() {
while(~scanf("%d%d", &n, &m)) {
init();
for(int i = ; i < m; i++) {
int u,v;scanf("%d%d", &u, &v);
Add(u, v);
}
for(int i = ; i <= n; i++)
if(!dfn[i]) tarjan(i);
for(int u = ; u <= n; u++)
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(belong[u] != belong[v]) {
add(belong[u], belong[v]);
}
}
int ans = -;
for(int i = ; i <= scc; i++)
ans = max(ans, DFS(i)); //所有点为起点的最长路径即为整张图的最长路径
printf("%d\n", ans);
}
}
2018-11-26
ZOJ 3795 Grouping (强连通缩点+DP最长路)的更多相关文章
- UVA11324 The Largest Clique (强连通缩点+DP最长路)
<题目链接> 题目大意: 给你一张有向图 G,求一个结点数最大的结点集,使得该结点集中的任意两个结点 u 和 v 满足:要么 u 可以达 v,要么 v 可以达 u(u,v相互可达也行). ...
- Grouping ZOJ - 3795 (tarjan缩点求最长路)
题目链接:https://cn.vjudge.net/problem/ZOJ-3795 题目大意:给你n个人,m个关系, 让你对这个n个人进行分组,要求:尽可能的分组最少,然后每个组里面的人都没有关系 ...
- zoj 3795 Grouping tarjan缩点 + DGA上的最长路
Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu Submit Status Practic ...
- BZOJ 5450 轰炸 (强连通缩点+DAG最长路)
<题目链接> 题目大意: 有n座城市,城市之间建立了m条有向的地下通道.你需要发起若干轮轰炸,每轮可以轰炸任意多个城市.但每次轰炸的城市中,不能存在两个不同的城市i,j满足可以通过地道从城 ...
- ZOJ 3795 Grouping 强连通分量-tarjan
一开始我还天真的一遍DFS求出最长链以为就可以了 不过发现存在有向环,即强连通分量SCC,有向环里的每个点都是可比的,都要分别给个集合才行,最后应该把这些强连通分量缩成一个点,最后保证图里是 有向无环 ...
- 【bzoj1179】[Apio2009]Atm Tarjan缩点+Spfa最长路
题目描述 输入 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每 ...
- Tarjan缩点+Spfa最长路【p3627】[APIO2009] 抢掠计划
Description Siruseri 城中的道路都是单向的.不同的道路由路口连接.按照法律的规定, 在每个路口都设立了一个 Siruseri 银行的 ATM 取款机.令人奇怪的是,Siruseri ...
- Gym - 101170B British Menu (强连通缩点+dp)
题意:求一个有向图上的最长路(每个强连通分量的点不超过5个) 首先对强连通分量缩点,暴力预处理出len[k][i][j]表示第k个强连通分量里的第i个点和第j个点之间的最长路径,设状态(k,i,f)表 ...
- ZOJ 3795 Grouping(scc+最长路)
Grouping Time Limit: 2 Seconds Memory Limit: 65536 KB Suppose there are N people in ZJU, whose ...
随机推荐
- Confluence 6 其他需要备份和恢复的地方
XML 备份被描述用于在 Confluence 备份使用的其他方法,例如升级和移动服务器.使用上面描述的备份和恢复方法也适用这些地方. 我们的 upgrade guide 不要求使用一个 XML 备份 ...
- AFN 请求报 415错误解决方案
使用 AFHTTPSessionManager 发起请求时 设置下面两句代码 manager.requestSerializer = [AFJSONRequestSerializer seriali ...
- js 判断输入的内容是否是整数
需求简介:列表有一列排序,其值只能是整数,不能是小数,在js中判断,并给出提示 解决思路:在js中先获取表单的值,然后用isNaN,然后查一下怎么把小数排除在外.我靠( ‵o′)凸,这只能算是半路把! ...
- ATM机模拟系统
实验要求 https://pan.baidu.com/s/1Sq5joWyVsNhY8DYiyI4UmQ 源代码 /*信1705-1 20173458 王嘉梁*/ package atm; impor ...
- stylus入门教程,在webstorm中配置stylus
转载:https://www.cnblogs.com/wenqiangit/p/9717715.html#undefined stylus特点 富于表现力.具有健壮性.功能丰富.动态编码 不需要写 ...
- Python变量的作用域
局部变量 局部变量是指在函数内部定义并使用的变量,他只在函数内部有效.即函数内部的名字只在函数运行时才会创建,在函数运行之前或者运行完毕之后,所有的名字就都不存在了.所以,如果在函数外部使用函数内部定 ...
- python面向对象三大特性之继承
继承是创建新类的方法,以下是几个概念 父类,基类,超类: 被继承的类 子类,派生类:继承而产出的类 单继承:继承一个父类 多继承:继承多个父类 继承: 什么是什么的关系 父类中没有的属性,在字类中出现 ...
- 修改Tomcat默认连接数
<Connector port=" protocol="HTTP/1.1" connectionTimeout=" redirectPort=" ...
- VS2017使用文档
参考链接:https://docs.microsoft.com/zh-cn/visualstudio/debugger/?view=vs-2017
- Context连接和断开的情况下的CRUD操作
连续情况下的CRUD操作是一项相当容易的任务,因为默认情况下,上下文会自动跟踪实体在其生命周期中发生的更改,AutoDetectChangesEnabled为true. 以下示例显示如何添加,更新和删 ...