ZOJ 3795 Grouping(Tarjan收缩点+DAG)
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}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<limits.h>
typedef long long LL;
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a ) const int maxn=100100;
const int maxm=300100;
struct node{
int u,v;
int next;
}e[maxm],e2[maxm];
int head[maxn],cntE,cntF;
int DFN[maxn],low[maxn],h[maxn];
int s[maxm],top,dex,cnt;
int belong[maxn],instack[maxn];
int dp[maxn],num[maxn];
int n,m;
void init()
{
top=cntE=cntF=0;
dex=cnt=0;
CLEAR(DFN,0);
CLEAR(head,-1);
CLEAR(instack,0);
CLEAR(num,0);//fuck num没清0wa了2小时
}
void addedge(int u,int v)
{
e[cntE].u=u;e[cntE].v=v;
e[cntE].next=head[u];
head[u]=cntE++;
}
void Tarjan(int u)
{
DFN[u]=low[u]=++dex;
instack[u]=1;
s[top++]=u;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].v;
if(!DFN[v])
{
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(instack[v])
low[u]=min(low[u],DFN[v]);
}
int v;
if(DFN[u]==low[u])
{
cnt++;
do{
v=s[--top];
belong[v]=cnt;
instack[v]=0;
}while(u!=v);
}
}
int dfs(int x)
{
if(dp[x]) return dp[x];
dp[x]=num[x];
for(int i=h[x];i!=-1;i=e2[i].next)
dp[x]=max(dp[x],dfs(e2[i].v)+num[x]);
return dp[x];
}
void work()
{
REPF(i,1,n)
if(!DFN[i]) Tarjan(i);
REPF(i,1,n)
num[belong[i]]++;
CLEAR(h,-1);
CLEAR(dp,0);
REPF(k,1,n)
{
for(int i=head[k];i!=-1;i=e[i].next)
{
int v=e[i].v;
if(belong[k]!=belong[v])
{
e2[cntF].u=belong[k];
e2[cntF].v=belong[v];
e2[cntF].next=h[belong[k]];
h[belong[k]]=cntF++;
}
}
}
int ans=0;
// cout<<"2333 "<<cnt<<endl;
REPF(i,1,cnt)
ans=max(ans,dfs(i));
printf("%d\n",ans);
}
int main()
{
int u,v;
while(~scanf("%d%d",&n,&m))
{
init();
for(int i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
}
work();
}
return 0;
}
版权声明:本文博客原创文章,博客,未经同意,不得转载。
ZOJ 3795 Grouping(Tarjan收缩点+DAG)的更多相关文章
- zoj 3795 Grouping tarjan缩点 + DGA上的最长路
Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu Submit Status Practic ...
- Grouping ZOJ - 3795 (tarjan缩点求最长路)
题目链接:https://cn.vjudge.net/problem/ZOJ-3795 题目大意:给你n个人,m个关系, 让你对这个n个人进行分组,要求:尽可能的分组最少,然后每个组里面的人都没有关系 ...
- ZOJ 3795 Grouping 强连通分量-tarjan
一开始我还天真的一遍DFS求出最长链以为就可以了 不过发现存在有向环,即强连通分量SCC,有向环里的每个点都是可比的,都要分别给个集合才行,最后应该把这些强连通分量缩成一个点,最后保证图里是 有向无环 ...
- ZOJ 3795 Grouping(scc+最长路)
Grouping Time Limit: 2 Seconds Memory Limit: 65536 KB Suppose there are N people in ZJU, whose ...
- ZOJ 3795 Grouping
大致题意是给n个人和m组关系,每组关系都是两个人s和t,表示s年龄不小于t的年龄,然后让你把这n个人分组,使得任何一个组里面的任意两人都不能直接或间接的得出这两个人的年龄大小关系. 思路:根据给出的关 ...
- ZOJ 3795 Grouping 求最长链序列露点拓扑
意甲冠军:特定n积分.m向边条. 该点被划分成多个集合随机的每个集合,使得2问题的关键是无法访问(集合只能容纳一个点) 问至少需要被分成几个集合. 假设没有戒指,接着这个话题正在寻求产业链最长的一个有 ...
- ZOJ 3795 Grouping (强连通缩点+DP最长路)
<题目链接> 题目大意: n个人,m条关系,每条关系a >= b,说明a,b之间是可比较的,如果还有b >= c,则说明b,c之间,a,c之间都是可以比较的.问至少需要多少个集 ...
- 2014 Super Training #8 G Grouping --Tarjan求强连通分量
原题:ZOJ 3795 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3795 题目大意:给定一个有向图,要求把点分为k个集 ...
- 「BZOJ1924」「SDOI2010」 所驼门王的宝藏 tarjan + dp(DAG 最长路)
「BZOJ1924」[SDOI2010] 所驼门王的宝藏 tarjan + dp(DAG 最长路) -------------------------------------------------- ...
随机推荐
- hdu1874畅通工程续 (dijkstra)
Problem Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行 ...
- 学习 easyui 之二:jQuery 的 ready 函数和 easyloader 的加载回调函数
Ready 事件不一定 ready 使用 easyloader 的时候,必须要注意到脚本的加载时机问题,easyloader 会异步加载模块,所以,你使用的模块不一定已经加载了.比如下面的代码. &l ...
- BZOJ 1038 ZJOI2008 瞭望塔 半平面交
题目大意及模拟退火题解:见 http://blog.csdn.net/popoqqq/article/details/39340759 这次用半平面交写了一遍--求出半平面交之后.枚举原图和半平面交的 ...
- 王立平--Failed to push selection: Read-only file system
往android模拟器导入资源,失败. 提示:仅仅读文件. mnt是仅仅读文件.应点击sdcard.,在导入
- 足球和oracle系列(3):oracle过程排名,世界杯第二回合战罢到来!
足球与oracle系列(3):oracle进程排名.世界杯次回合即将战罢! 声明: 这不是技术文档,既然学来几招oracle简单招式.就忍不了在人前卖弄几下.纯为茶余饭后与数朋库友的插科 ...
- Access之C#连接Access
原文:Access之C#连接Access 如果是个人用的小程序的话.一般都推荐用Sqlite和Access 使用SQlite数据库需要安装SQLite驱动,详情:SQLite之C#连接SQLite 同 ...
- C#中的关键字
abstract event new struct as explicit null switch base extern object this bool false operator throw ...
- 【Hibernate步步为营】--双向关联一对一映射具体解释(一)
一对一的映射在对象模型中是常常见到的,为了将对象模型转换为关系模型就必须在映射文件里进行配置,上篇文章讨论了一对一映射的单向关联的情况,重点是<one-to-one>标签的使用,须要在映射 ...
- cocos2D(八)---- CCMenu && CCMenuItem
些菜单项让用户開始游戏.暂停\继续游戏.打开\关闭音乐或者是返回到上一个界面,比方以下两张图中用红色线框标记的菜单项 我们能够使用CCMenu和CCMenuItem实现上述的菜单功能,CCMe ...
- IOS成长之路-Nsstring搜索方法rangeOfString
NSString *str1 = @"can you \n speak English"; NSString *str = @"\n"; //在str1该字符串 ...