ZOJ 3795 Grouping
大致题意是给n个人和m组关系,每组关系都是两个人s和t,表示s年龄不小于t的年龄,然后让你把这n个人分组,使得任何一个组里面的任意两人都不能直接或间接的得出这两个人的年龄大小关系。
思路:根据给出的关系建图,问题转化为求图里面的一个最长链。考虑简单情形:图里面没有回路,那么直接dp+记忆化搜索就OK了,len[u] = max(len[u],len[v] + 1),(u,v相邻)。若有回路,那么利用tarjan进行缩点,把一个强连通分量里面的所有点缩成一个点,该点的权重就是分量里面点的个数,仍利用上述方法求解即可 len[u] = max(len[u],len[v] + w[u])。
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 100010;
int ind, top, cnt;
int vis[MAXN], len[MAXN], head[MAXN], shead[MAXN];
int dfn[MAXN], low[MAXN], st[MAXN], num[MAXN], w[MAXN];
struct Edge{
int to, next;
};
Edge edge[3*MAXN], sedge[3*MAXN];
void addEdge(int u, int v, int k){
edge[k].to = v;
edge[k].next = head[u];
head[u] = k;
}
void saddEdge(int u, int v, int k){
sedge[k].to = v;
sedge[k].next = shead[u];
shead[u] = k;
}
void tarjan(int u){
dfn[u] = low[u] = ++ind;
vis[u] = 1, st[++top] = u;
for(int i = head[u]; ~i; i = edge[i].next){
int v = edge[i].to;
if(!dfn[v]){
tarjan(v);
low[u] = min(low[u], low[v]);
}else if(vis[v]) low[u] = min(low[u], dfn[v]);
}
int tmp;
if(low[u] == dfn[u]){
do{
tmp = st[top--];
num[tmp] = cnt;
vis[tmp] = 0;
}while(tmp != u);
cnt ++;
}
}
int dfs(int u){
vis[u] = 1, len[u] = w[u];
for(int i = shead[u]; ~i; i = sedge[i].next){
int v = sedge[i].to;
if(vis[v]) len[u] = max(len[u], len[v] + w[u]);
else len[u] = max(len[u], dfs(v) + w[u]);
}
return len[u];
}
int solve(int n){
int k = 1;
ind = top = 0;
cnt = 1;
memset(w, 0, sizeof(w));
memset(dfn, 0, sizeof(dfn));
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= n; i ++)
if(!dfn[i]) tarjan(i);
memset(shead, -1, sizeof(shead));
for(int i = 1; i <= n; i ++){
w[num[i]] ++;
for(int j = head[i]; ~j; j = edge[j].next){
int u = edge[j].to;
if(num[i] != num[u]) saddEdge(num[i], num[u], k++);
}
}
int ans = 1;
memset(vis, 0, sizeof(vis));
for(int i = 1; i < cnt; i ++){
if(!vis[i]) dfs(i);
ans = max(ans, len[i]);
}
return ans;
}
int main(){
int n, m;
#ifndef ONLINE_JUDGE
freopen("in.cpp", "r", stdin);
#endif
while(~scanf("%d%d", &n, &m)){
int u, v;
memset(head, -1, sizeof(head));
for(int i = 1; i <= m; i ++){
scanf("%d%d", &u, &v);
addEdge(v, u, i);
}
printf("%d\n", solve(n));
}
return 0;
}
ZOJ 3795 Grouping的更多相关文章
- zoj 3795 Grouping tarjan缩点 + DGA上的最长路
Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu Submit Status Practic ...
- 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向边条. 该点被划分成多个集合随机的每个集合,使得2问题的关键是无法访问(集合只能容纳一个点) 问至少需要被分成几个集合. 假设没有戒指,接着这个话题正在寻求产业链最长的一个有 ...
- 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 ...
- ZOJ 3795 Grouping (强连通缩点+DP最长路)
<题目链接> 题目大意: n个人,m条关系,每条关系a >= b,说明a,b之间是可比较的,如果还有b >= c,则说明b,c之间,a,c之间都是可以比较的.问至少需要多少个集 ...
- ZOJ 3795 Grouping 强连通分量-tarjan
一开始我还天真的一遍DFS求出最长链以为就可以了 不过发现存在有向环,即强连通分量SCC,有向环里的每个点都是可比的,都要分别给个集合才行,最后应该把这些强连通分量缩成一个点,最后保证图里是 有向无环 ...
- 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,现在要 ...
- 2014 Super Training #8 G Grouping --Tarjan求强连通分量
原题:ZOJ 3795 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3795 题目大意:给定一个有向图,要求把点分为k个集 ...
随机推荐
- GDI+ 如何将图片绘制成圆形的图片
大概意思就是不生成新的图片,而是将图片转换为圆形图片. 实现代码如下: private Image CutEllipse(Image img, Rectangle rec, Size size) { ...
- c#的多线程
多线程的使用方法: Thread t = new Thread(new ThreadStart (StartMethod)); t.Start(); private void StartMethod( ...
- 可以自动安装mysql数据库的一个shell脚本
发布:thatboy 来源:脚本学堂 [大 中 小] 分享一例shell脚本,可以实现mysql数据库的自动安装,脚本写的不错,无论是用来学习,还是生产环境中应用,都是不错的,有需要的朋友 ...
- C#多线程(二)
一.线程池 每次创建一个线程,都会花费几百微秒级别的时间来创建一个私有的局部栈,每个线程默认使用1M的内存.这个可以在使用Thread类的构造函数时设置: new Thread(new ThreadS ...
- Linux下GPIO驱动(一) ----一个简单的LED驱动
/******************************* * *杂项设备驱动:miscdevice *majior=10; * * *****************************/ ...
- Nodejs初学者福音
Nodejs+Express+MongoDb 搭建个人博客 001 我喜欢把任务或者工作分解成工作流来完成,如下,后面将会按照流程来详述,希望能为Nodejs初学者及推广Nodejs做出些努力. n ...
- 编写jQuery插件--实现返回顶部插件
国庆过去一周多了,作为IT界的具有严重’工作狂‘性质的宅人,居然还没走出玩耍的心情,拖了程序猿的脚后跟了.最近工作不顺,心情不佳,想吐槽下公司,想了还是厚道点,以彼之道还施彼身,觉得自己也和他们同流合 ...
- hdu5548
2015ACM/ICPC亚洲区上海站LCM WALK 题意:定义了一种走法,就是从当前的点为sx,sy,可以走到ex,ey;并且ex = sx + z,或者 ey = sy + z, 其中z为lcm( ...
- Unity3d Shader开发(二)SubShader
(1)SubShader Unity中的每一个着色器都包含一个subshader的列表,当Unity需要显示一个网格时,它能发现使用的着色器,并提取第一个能运行在当前用户的显示卡上的子着色器. 当Un ...
- 通过I2C总线向EEPROM中写入数据,记录开机次数
没买板子之前,用protues画过电路图,实现了通过i2c总线向EEPROM中写入和读出数据. 今天,在自己买的板子上面写关于i2c总线的程序,有个地方忘了延时,调程序的时候很蛋疼.下面说说我对I2c ...