题目链接:https://cn.vjudge.net/problem/ZOJ-3795

题目大意:给你n个人,m个关系, 让你对这个n个人进行分组,要求:尽可能的分组最少,然后每个组里面的人都没有关系。

具体思路:首先对年龄相同的人进行缩点,这些人是肯定不能在同一个组里面的。然后缩完点之后找出剩下的图中一条最长路(每个点的权值就是缩完点之后当前联通块里面的人的个数),我们找出最长路之后(最长路通过拓扑排序判断),这就是答案了。即使有别的图中的人,我们都可以放进这个最长链形成的分组个数中。

AC代码:

 #include<iostream>
#include<stdio.h>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
# define ll long long
# define inf 0x3f3f3f3f
const int maxn = 2e5+;
int n,m,num,ord,col;
int head[maxn],low[maxn],dfn[maxn];
int cont[maxn],in[maxn];
int istack[maxn],dp[maxn];
struct node
{
int fr;
int to;
int nex;
} edge[maxn<<];
vector<int>Map[maxn];
stack<int>q;
void init()
{
num=;
ord=;
col=;
while(!q.empty())
q.pop();
for(int i=; i<=n; i++)
{
head[i]=-;
low[i]=;
dfn[i]=;
cont[i]=;
in[i]=;
istack[i]=;
dp[i]=;
}
}
void addedge(int fr,int to)
{
edge[num].fr=fr;
edge[num].to=to;
edge[num].nex=head[fr];
head[fr]=num++;
}
void dfs(int u)
{
low[u]=dfn[u]=++ord;
q.push(u);
for(int i=head[u]; i!=-; i=edge[i].nex)
{
int to=edge[i].to;
if(dfn[to]==)
{
dfs(to);
low[u]=min(low[u],low[to]);
}
else if(istack[to]==)
{
low[u]=min(low[u],dfn[to]);
}
}
if(low[u]==dfn[u])
{
int t;
col++;
do
{
t=q.top();
q.pop();
istack[t]=col;
cont[col]++;
}
while(t!=u);
}
}
void tarjan()
{
for(int i=; i<=n; i++)
{
if(!dfn[i])
dfs(i);
}
}
void topsort()
{
while(!q.empty())
q.pop();
for(int i=; i<=col; i++)
{
if(!in[i])
q.push(i);
dp[i]=cont[i];
}
while(!q.empty())
{
int top=q.top();
q.pop();
for(int i=; i<Map[top].size(); i++)
{
int to=Map[top][i];
dp[to]=max(dp[to],dp[top]+cont[to]);
if(--in[to]==)
{
q.push(to);
}
}
}
}
int main()
{
while(~scanf("%d %d",&n,&m)){
init();
int st,ed;
for(int i=; i<=m; i++)
{
scanf("%d %d",&st,&ed);
addedge(st,ed);
}
tarjan();
for(int i=; i<=col; i++)
{
Map[i].clear();
}
for(int i=; i<num; i++)//注意这个地方要重新建图。
{
if(istack[edge[i].fr]!=istack[edge[i].to])
{
Map[istack[edge[i].fr]].push_back(istack[edge[i].to]);
in[istack[edge[i].to]]++;
}
}
topsort();
int maxx=;
for(int i=; i<=col; i++)
{
maxx=max(maxx,dp[i]);
}
printf("%d\n",maxx);
}
return ;
}

 

Grouping ZOJ - 3795 (tarjan缩点求最长路)的更多相关文章

  1. BZOJ5450: 轰炸(水题,Tarjan缩点求最长路)

    5450: 轰炸 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 43  Solved:18[Submit][Status][Discuss] Desc ...

  2. Tarjan缩点+Spfa最长路【p3627】[APIO2009] 抢掠计划

    Description Siruseri 城中的道路都是单向的.不同的道路由路口连接.按照法律的规定, 在每个路口都设立了一个 Siruseri 银行的 ATM 取款机.令人奇怪的是,Siruseri ...

  3. 【bzoj1179】[Apio2009]Atm Tarjan缩点+Spfa最长路

    题目描述 输入 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每 ...

  4. HDU 4612 Warm up tarjan缩环+求最长链

    Warm up Problem Description   N planets are connected by M bidirectional channels that allow instant ...

  5. BZOJ1093 [ZJOI2007]最大半连通子图 【tarjan缩点 + DAG最长路计数】

    题目 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意 两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G ...

  6. [luogu3627 APIO2009] 抢掠计划 (tarjan缩点+spfa最长路)

    传送门 Description Input 第一行包含两个整数 N.M.N 表示路口的个数,M 表示道路条数.接下来 M 行,每行两个整数,这两个整数都在 1 到 N 之间,第 i+1 行的两个整数表 ...

  7. 训练赛 Grouping(强连通分量缩点 + DAG求最长路)

    http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=158#problem/F 大致题意:给出n个人和m种关系(ti,si),表示ti ...

  8. POJ-3352 Road Construction,tarjan缩点求边双连通!

    Road Construction 本来不想做这个题,下午总结的时候发现自己花了一周的时间学连通图却连什么是边双连通不清楚,于是百度了一下相关内容,原来就是一个点到另一个至少有两条不同的路. 题意:给 ...

  9. tarjan 缩点 求 scc

    算法学自 BYVoid https://www.byvoid.com/zhs/blog/scc-tarjan/ 这个写得很清楚了 当然 你可能不这么认为 而且 如果是让我 一开始就从这个博客 学 ta ...

随机推荐

  1. mongoDB-权限控制

    启动服务D:\MongoDB\Server\3.6\bin>mongod.exe --dbpath D:\MongoDB\Server\3.6\data 扩展 无认证启动:mongod --po ...

  2. C++基础知识--DAY1

    1. C语言是面向过程的语言,C++是面向对象的语言,相对于C语言来说,C++语法规则更为严格,其存在类型增强的问题. 类型增强,顾名思义就是C++相对于C语言来说有更加严格的类型检查,很多C语言的语 ...

  3. Android Eclipse 安装教程 hosts替换

    http://www.cnblogs.com/Potato-lover/p/5582542.html 第一步,也是最为关键的一步——修改hosts文件 为什么说是最关键的一步呢?因为接下来的操作,我们 ...

  4. Linux 多线程 - 线程异步与同步机制

    Linux 多线程 - 线程异步与同步机制 I. 同步机制 线程间的同步机制主要包括三个: 互斥锁:以排他的方式,防止共享资源被并发访问:互斥锁为二元变量, 状态为0-开锁.1-上锁;开锁必须由上锁的 ...

  5. Qt ------ excel 操作

    写 excel // step1:连接控件 QAxObject* excel = new QAxObject(this); excel->setControl("Excel.Appli ...

  6. C++: 带参数回调函数和不带参数的回调函数;

    在C++中,回调函数的应用比较广泛且重要. 通过传递函数指针到其他地方,能够实现远程回调的作用,能够实现远程调用而不需要事件触发信号或者其他机制来实现,方便而快捷: 首先,回调函数有两种形式:  静态 ...

  7. qml: C++调用qml函数

    C++调用qml函数,是通过下面的函数实现的: bool QMetaObject::invokeMethod(QObject *obj, const char *member, Qt::Connect ...

  8. golang 热升级

    需求场景 干净利落地升级正在运行的agent程序.适用于Devops团队. 目标: 不关闭现有连接:例如我们不希望关掉已部署的运行中的程序.但又想不受限制地随时升级服务. 新的进程要能够启动并替换掉旧 ...

  9. C# 主动发起请求代码

    本文用于写代码是给提示 private string GetHW(string uri) { string returnStr = ""; HttpWebRequest hwReq ...

  10. gcc编译出现dlopen、dlerror、dlsym、dlcolse的解决方法

      ➜  test_sqlite3 gcc *.c -I . -o xixi -pthread      /tmp/cckGKTrr.o: In function `unixDlOpen': sqli ...