ZOJ 3795 Grouping(scc+最长路)
Grouping
Time Limit: 2 Seconds Memory Limit: 65536 KB
Suppose there are N people in ZJU, whose ages are unknown. We have some messages about them. The i-th message shows that the age of person si is not smaller than the age of person ti. Now we need to divide all these N people into several groups. One's age shouldn't be compared with each other in the same group, directly or indirectly. And everyone should be assigned to one and only one group. The task is to calculate the minimum number of groups that meet the requirement.
Input
There are multiple test cases. For each test case: The first line contains two integers N(1≤ N≤ 100000), M(1≤ M≤ 300000), N is the number of people, and M is is the number of messages. Then followed by M lines, each line contain two integers si and ti. There is a blank line between every two cases. Process to the end of input.
Output
For each the case, print the minimum number of groups that meet the requirement one line.
Sample Input
4 4
1 2
1 3
2 4
3 4
Sample Output
3
Hint
set1= {1}, set2= {2, 3}, set3= {4}
题目给出N个点 , M条边, 然后问一些相关联的人(存在一条路u -> v)不能分在同一组 , 最少分的组的数目 。
这样肯定要求一个 scc .. 那么在同一个scc里面的人(假设有w个人)都要拆分成w组 , 那么我们以这个w作为
scc图的点权 。 目的是所有 scc图(DAG) 的最长路所构成的权 ,取最大。
最长路用一个记忆化搜索即可 , 训练的时候不会这么用 , 卡蒙了~~ 。
#include <bits/stdc++.h>
using namespace std;
const int N = ; int pre[N] , lowlink[N] , sccno[N] , dfs1_clock , scc_cnt ;
stack<int>st;
int n , m ;
int w[N] , dep_w[N];
bool vis[N];
int in[N];
int dp[N]; int eh[N] , et[N<<] ,nxt[N<<] , tot ; void addedge( int u , int v )
{
et[tot] = v , nxt[tot] = eh[u] , eh[u] = tot ++ ;
} struct node
{
int u , v ;
}e[N*]; void dfs1( int u )
{
pre[u] = lowlink[u] = ++dfs1_clock;
st.push(u);
for( int i = eh[u]; ~i ; i = nxt[i] ){
int v = et[i] ;
if(!pre[v]){
dfs1(v);
lowlink[u] = min(lowlink[u],lowlink[v]);
}
else if( !sccno[v] ){
lowlink[u] = min( lowlink[u] , pre[v] );
}
}
if( lowlink[u] == pre[u] )
{
scc_cnt++;
for(;;){
int x = st.top(); st.pop();
sccno[x] = scc_cnt ;
if( x == u ) break;
}
}
} void find_scc()
{
dfs1_clock = scc_cnt = ;
memset ( pre , , sizeof pre ) ;
memset ( sccno , , sizeof sccno ) ;
while( !st.empty() ) st.pop(); for( int i = ; i <= n ; ++i ){
if( !pre[i] )dfs1(i);
}
} void init()
{ tot= ;
memset( eh , - ,sizeof eh );
memset( dp , - ,sizeof dp );
memset( w , ,sizeof w );
memset( vis ,false , sizeof vis );
memset( in , , sizeof in );
} void dfs( int u )
{
if( dp[u] == - ){
int sum_now = w[u] ;
for( int i = eh[u] ; ~i ; i = nxt[i] ){
int v = et[i];
dfs(v);
sum_now = max( sum_now , w[u] + dp[v] );
}
dp[u] = sum_now;
}
} void run()
{
int u , v ;
init();
for( int i = ; i < m ;++i ){
scanf("%d%d",&e[i].u,&e[i].v);
addedge( e[i].u , e[i].v );
}
find_scc();
tot = ;
memset(eh , - , sizeof eh ); for( int i = ;i < m ;++i ){
if( sccno[e[i].u] != sccno[e[i].v] ){
addedge( sccno[e[i].u] , sccno[e[i].v] );
in[ sccno[e[i].v] ] ++;
}
} for( int i = ; i <= n ; ++i )w[ sccno[i] ] ++ ; int ans = ;
for( int i = ; i <= scc_cnt ; ++i ) if( !in[i] ) addedge(,i);
dfs();
for( int i = ; i <= scc_cnt ; ++i ) ans = max( ans , dp[i] );
printf("%d\n",ans);
} int main()
{
#ifdef LOCAL
freopen("in","r",stdin);
#endif
ios::sync_with_stdio();
while( ~scanf("%d%d",&n,&m))run();
}
ZOJ 3795 Grouping(scc+最长路)的更多相关文章
- ZOJ 3795 Grouping 求最长链序列露点拓扑
意甲冠军:特定n积分.m向边条. 该点被划分成多个集合随机的每个集合,使得2问题的关键是无法访问(集合只能容纳一个点) 问至少需要被分成几个集合. 假设没有戒指,接着这个话题正在寻求产业链最长的一个有 ...
- zoj 3795 Grouping tarjan缩点 + DGA上的最长路
Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu Submit Status Practic ...
- ZOJ 3795 Grouping (强连通缩点+DP最长路)
<题目链接> 题目大意: n个人,m条关系,每条关系a >= b,说明a,b之间是可比较的,如果还有b >= c,则说明b,c之间,a,c之间都是可以比较的.问至少需要多少个集 ...
- zoj 3088 Easter Holidays(最长路+最短路+打印路径)
Scandinavians often make vacation during the Easter holidays in the largest ski resort Are. Are prov ...
- ZOJ 3795 Grouping 强连通分量-tarjan
一开始我还天真的一遍DFS求出最长链以为就可以了 不过发现存在有向环,即强连通分量SCC,有向环里的每个点都是可比的,都要分别给个集合才行,最后应该把这些强连通分量缩成一个点,最后保证图里是 有向无环 ...
- ZOJ 3795 Grouping
大致题意是给n个人和m组关系,每组关系都是两个人s和t,表示s年龄不小于t的年龄,然后让你把这n个人分组,使得任何一个组里面的任意两人都不能直接或间接的得出这两个人的年龄大小关系. 思路:根据给出的关 ...
- ZOJ 3795 Grouping(Tarjan收缩点+DAG)
Suppose there are N people in ZJU, whose ages are unknown. We have some messages about them. The i-t ...
- Grouping ZOJ - 3795 (tarjan缩点求最长路)
题目链接:https://cn.vjudge.net/problem/ZOJ-3795 题目大意:给你n个人,m个关系, 让你对这个n个人进行分组,要求:尽可能的分组最少,然后每个组里面的人都没有关系 ...
- ZOJ 3795:Grouping(缩点+最长路)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5303 题意:有n个人m条边,每条边有一个u,v,代表u的年龄大于等于v,现在要 ...
随机推荐
- Oracle学习笔记<3>
单值函数 1.函数的分类 Oracle数据库中函数分为两类: 1)单值函数 n条数据经过函数处理得到n条结果 例如:查询所有员工last_name,并以全部大写形式输出 2)多值函数(组函数) n条数 ...
- python介绍(变量,if,while)
python介绍(变量,if,while): python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹 打发时间,决心开发一个新 ...
- Vue证明题
看来我需要对我的vue能力做一个证明了~~ 最近辞职了,又逢病重,找工作的时候发现对vue要求蛮高的,说会不行,还必须要有过vue的项目. 我这种半路出家的哪里来的vue的项目,公司又不是那种一线互联 ...
- JS事件循环(Event Loop)机制
前言 众所周知,为了与浏览器进行交互,Javascript是一门非阻塞单线程脚本语言. 为何单线程? 因为如果在DOM操作中,有两个线程一个添加节点,一个删除节点,浏览器并不知道以哪个为准,所以只能选 ...
- redis 分布式锁的正确实现方式
前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...
- 【转】java中JVM的原理
转载自https://blog.csdn.net/witsmakemen/article/details/28600127/ 一.java虚拟机的生命周期: Java虚拟机的生命周期 一个运行中的Ja ...
- c++后台开发面试常见知识点总结(四)数据库
数据库的索引类型 聚集索引和非聚集索引的区别(叶节点存储内容) 唯一性索引和主码索引的区别 索引的优缺点,什么时候使用索引,什么时候不能使用索引(重点) 索引最左前缀问题 数据库中事务的ACID 数据 ...
- 目标检测中roi的有关操作
1.roi pooling 将从rpn中得到的不同Proposal大小变为fixed_length output, 也就是将roi区域的卷积特征拆分成为H*W个网格,对每个网格进行maxpooling ...
- 数据结构---Java---Hastable
1.概述 1.1 Hashtable是线程安全的: 1.2 源码 public class Hashtable<K,V> extends Dictionary<K,V> imp ...
- Excel表格 函数
1.四则运算(加.减.乘.除).求和.平均.计数.最值. 2. 逻辑函数 (IF函数.NOT函数.等) 3.时间和日期 ( NOW 返回当前日期和时间.等) 4.数学与三角函数 5.文本 ( LOWE ...