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个集 ...
随机推荐
- Oracle 关于事物的描述
事物在Oracle中的4种状态: commit--提交 rollback--全部回滚 savepoint name;--定义一个回滚到这里的点:例如:savepoint a; rollback to ...
- DataGridView绘制序号
1.找到RowPostPaint事件 2.写入事件 /// <summary> /// 绘制序号 /// </summary> private void dgvStatemen ...
- off() 方法 与 unbind() 方法移除绑定事件的处理程序。one()函数用于为每个匹配元素的一个或多个事件绑定一次性事件处理函数
off() 方法移除用.on()绑定的事件处理程序. unbind() 方法移除用.bind()绑定的事件处理程序. 从 jQuery 1.7开始, .on() 和 .off()方法是最好的元素上附加 ...
- 测试MySQL事务管理
1.MySQL 版本 mysql> select version(); +------------+ | version() | +------------+ -log | +--------- ...
- 我的PHP之旅--数据库连接MySQL服务器,添加 删除 查询
PHP连接MySQL服务器 连接MySQL的方法:mysql_connect(); 语法:resource $link = mysql_connect($hostname, $username, $p ...
- Dynamic Programming (DP) 问题总结
所有的 DP 问题都可以简单得用 Recursion 的方式实现.这通常是最容易想到的思路. 问题是这种实现不够 efficient,存在 subproblem 被重复计算的情况.有两种解决这个问题的 ...
- 坚持Delphi的厂商与产品
能记一个算一个吧... 招商银行的企业网银是用Delphi开发的,听说招商有不少软件都是用Delphi开发的. 广州酷狗音乐招Delphi开发 对程序员来说,Delphi写的比较有名的软件莫过于Dev ...
- 对于Unicode编码在js中和html中
1.对于Unicode在js中 var a="\u9102WQW121" 中"\"是需要转义的,直接在页面输出的效果
- Android 设置控件可见与不可见
通常控件的可见与不可见分为三种情况 第一种 gone 表示不可见并且不占用空间 第二种 visible 表示可见 第三种 invisible 表示不 ...
- chrome插件 postman插件 接口测试、API & HTTP 请求调试工具
Postman 是一个非常棒的Chrome扩展,提供功能强大的API & HTTP 请求调试. 它能够发送任何类型的HTTP requests (GET, HEAD, POST, PUT..) ...