Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

Description

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}

思路:题目给出a, b  是指a不小于b, 即a可以等于b, a到b拉一条有向边,多个相等的时候会成环,直接求最长路则会死循环, 所以应该先用tarjan把强联通分量缩成一个点,点权就代表该强联通分量中点的数目,再求最长路

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
#include <stack>
#include <vector>
using namespace std;
const int N = 211111;
const int E = 333333;
vector<int> G[N];
int pre[N], low[N], sccno[N], num[N], dfs_ck, scc_cnt;
stack<int> s; void dfs(int u)
{
pre[u] = low[u] = ++dfs_ck;
s.push(u);
for(int i = 0; i < G[u].size(); ++i) {
int v = G[u][i];
if(!pre[v]) {
dfs(v);
low[u] = min(low[u], low[v]);
} else if(!sccno[v]) {
low[u] = min(low[u], pre[v]);
}
}
if(low[u] == pre[u])
{
scc_cnt++;
for(;;) {
num[scc_cnt]++;
int x = s.top(); s.pop();
sccno[x] = scc_cnt;
if(x == u) break;
}
}
}
void find_scc(int n)
{
dfs_ck = scc_cnt = 0;
memset(sccno, 0, sizeof sccno);
memset(pre, 0, sizeof pre);
memset(num, 0, sizeof num);
for(int i = 1; i <= n; ++i) if(!pre[i]) dfs(i);
} int dp[N];
vector<int> G2[N]; void init(int n)
{
for(int i = 0; i <= n; ++i) G[i].clear();
for(int i = 0; i <= n; ++i) G2[i].clear();
while(!s.empty()) s.pop();
} int get(int u)
{
int& res = dp[u];
if(res != -1) return res; res = num[ u ]; // 一开始写成 res = num[ sccno[u] ], wa, 建图的时候已经是通过scc编号来建图了
int sx = G2[u].size();
for(int j = 0; j < sx; ++j) res = max(res, get(G2[u][j]) + num[ u ]);
return res;
} int main()
{
int n, m;
while(~scanf("%d%d", &n, &m))
{
int u, v;
init(n);
for(int i = 0; i < m; ++i) {
scanf("%d%d", &u, &v);
G[u].push_back(v); }
find_scc(n);
// printf("%d\n", scc_cnt);
// for(int i = 1; i <= n; ++i) printf("%d %d\n", i, sccno[i]); for(int i = 1; i <= n; ++i) {
int sx = G[i].size();
for(int j = 0; j < sx; ++j) {
int v = G[i][j];
if(sccno[i] != sccno[v]) {
G2[ sccno[i] ].push_back(sccno[v]); //通过scc编号来建图
// printf("%d %d\n", sccno[i], sccno[v]);
}
}
} memset(dp, -1, sizeof dp);
int ans = 0;
for(int i = 1; i <= scc_cnt; ++i) ans = max(ans, get(i));
printf("%d\n", ans);
}
}

  

zoj 3795 Grouping tarjan缩点 + DGA上的最长路的更多相关文章

  1. Grouping ZOJ - 3795 (tarjan缩点求最长路)

    题目链接:https://cn.vjudge.net/problem/ZOJ-3795 题目大意:给你n个人,m个关系, 让你对这个n个人进行分组,要求:尽可能的分组最少,然后每个组里面的人都没有关系 ...

  2. ZOJ 3795 Grouping (强连通缩点+DP最长路)

    <题目链接> 题目大意: n个人,m条关系,每条关系a >= b,说明a,b之间是可比较的,如果还有b >= c,则说明b,c之间,a,c之间都是可以比较的.问至少需要多少个集 ...

  3. 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 ...

  4. NYOJ_矩形嵌套(DAG上的最长路 + 经典dp)

    本题大意:给定多个矩形的长和宽,让你判断最多能有几个矩形可以嵌套在一起,嵌套的条件为长和宽分别都小于另一个矩形的长和宽. 本题思路:其实这道题和之前做过的一道模版题数字三角形很相似,大体思路都一致,这 ...

  5. UVa 10285 最长的滑雪路径(DAG上的最长路)

    https://vjudge.net/problem/UVA-10285 题意: 在一个R*C的整数矩阵上找一条高度严格递减的最长路.起点任意,但每次只能沿着上下左右4个方向之一走一格,并且不能走出矩 ...

  6. HDU 3249 Test for job (有向无环图上的最长路,DP)

     解题思路: 求有向无环图上的最长路.简单的动态规划 #include <iostream> #include <cstring> #include <cstdlib ...

  7. Vulnerable Kerbals CodeForces - 772C【拓展欧几里得建图+DAG上求最长路】

    根据拓展欧几里得对于同余方程 $ax+by=c$ ,有解的条件是 $(a,b)|c$. 那么对于构造的序列的数,前一个数 $a$  和后一个数 $b$ ,应该满足 $a*x=b(mod m)$ 即 $ ...

  8. ZOJ 3795 Grouping(scc+最长路)

    Grouping Time Limit: 2 Seconds      Memory Limit: 65536 KB Suppose there are N people in ZJU, whose ...

  9. ZOJ 3795 Grouping 强连通分量-tarjan

    一开始我还天真的一遍DFS求出最长链以为就可以了 不过发现存在有向环,即强连通分量SCC,有向环里的每个点都是可比的,都要分别给个集合才行,最后应该把这些强连通分量缩成一个点,最后保证图里是 有向无环 ...

随机推荐

  1. 【python】mysqlDB转xml中的编码问题

    背景:有mysql数据库,将数据从数据库中读取,并存储到xml中 采用了MySQLdb和lxml两个库 具体编码处理过程如下: . 指定mysql的编码方式 .取数据库data->判断data类 ...

  2. Android Studio新建了一个项目看不到手机界面的效果

    我今天新建了一个项目,但是在这里却看不到手机的界面效果,如下图:

  3. poj1308(简单并查集)

    题目链接:http://poj.org/problem?id=1308 题意:x, y 表示x 与 y连接,给出一波这样的数据,问这组数据能否构成树,即不能形成回路,不能有多个根节点:要注意可以是空树 ...

  4. java 小数点处理

    public class Test { public static void main(String[] args) { double i = 3.856; // 舍掉小数取整 System.out. ...

  5. C#的正则表达式

    using System; using System.Collections; using System.Collections.Generic; using System.IO; using Sys ...

  6. ActiveMQ的几种消息持久化机制

    为了避免意外宕机以后丢失信息,需要做到重启后可以恢复消息队列,消息系统一般都会采用持久化机制. ActiveMQ的消息持久化机制有JDBC,AMQ,KahaDB和LevelDB,无论使用哪种持久化方式 ...

  7. 浅析配置更快的Eclipse方法

    很多人感觉自己的elipse启动比较慢,其实并不是因为装的插件太多或者是导入的项目有点大,而是因为参数的设置不合理导致的.可以在eclipse.ini里面添加-Xloggc:gc.log看看启动的日志 ...

  8. 《图形学》实验四:中点Bresenham算法画直线

    开发环境: VC++6.0,OpenGL 实验内容: 使用中点Bresenham算法画直线. 实验结果: 代码: //中点Bresenham算法生成直线 #include <gl/glut.h& ...

  9. Code Review for SSIS package

    以下是我对SSIS包进行code review的一些建议,如果有其他更好的方案欢迎拍砖. A. 查看是否使用了最优的解决方案 1. 最优的结构视图 2. 解决方案,包,任务,组建,参数的命名使用了易读 ...

  10. jquery mobile 转场闪屏的解决

     jqm转场闪屏是用phonegap生成apk非常容易遇到的问题,暂时貌似还是没有完美的解决方案,网上暂时有一些方案,个人都尝试了一下发现还是改背景比较有效,总结如下: 改变默认css文件: .ui- ...