【强连通缩点+记忆化搜索求最长路】ZOJ_3795_Grouping

来源:互联网 发布:人人网账号共享 知乎 编辑:程序博客网 时间:2024/05/22 02:07
ZOJ Problem Set - 3795
Grouping

Time Limit: 2 Seconds      Memory Limit: 65536 KB

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 41 21 32 43 4

Sample Output

3

Hint

set1= {1}, set2= {2, 3}, set3= {4}


Author: LUO, Jiewei
Source: ZOJ Monthly, June 2014

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn=112345;int head[maxn],cnt,dfn[maxn],low[maxn],instack[maxn],Stack[maxn],top,idx,f[maxn],sum[maxn],deg[maxn],head1[maxn],cnt1,dis[maxn],ans;struct node{    int to,next;}e[maxn*3],ee[maxn*3];void Init(){    memset(head,-1,sizeof(head));    cnt=idx=top=ans=0;    memset(dfn,0,sizeof(dfn));    memset(instack,0,sizeof(instack));    memset(sum,0,sizeof(sum));    memset(deg,0,sizeof(deg));    memset(head1,-1,sizeof(head1));    cnt1=0;    memset(dis,0,sizeof(dis));}void add(int u,int v){    e[cnt].to=v;    e[cnt].next=head[u];    head[u]=cnt++;}void add1(int u,int v){    ee[cnt1].to=v;    ee[cnt1].next=head1[u];    head1[u]=cnt1++;}void tarjan(int u){/*强连通缩点*/    low[u]=dfn[u]=++idx;    instack[u]=1;    Stack[top++]=u;    for(int i=head[u];~i;i=e[i].next){        int v=e[i].to;        if(!dfn[v]){            tarjan(v);            low[u]=min(low[u],low[v]);        }        else if(instack[v])            low[u]=min(low[u],dfn[v]);    }    if(low[u]==dfn[u]){        int v;        ans++;        do{            v=Stack[--top];            instack[v]=0;            f[v]=ans;            sum[ans]++;        }while(u!=v);    }}int dfs(int x){/*记忆化搜索求最长路*/    if(dis[x])        return dis[x];    int mmax=0;    for(int i=head1[x];~i;i=ee[i].next){        int v=ee[i].to;        mmax=max(mmax,dfs(v));    }    return dis[x]=sum[x]+mmax;}int main(){    int n,m,u,v;    while(~scanf("%d%d",&n,&m)){        Init();        while(m--){            scanf("%d%d",&u,&v);            add(u,v);        }        for(int i=1;i<=n;i++)            if(!dfn[i])                tarjan(i);        for(int u=1;u<=n;u++){/*重新建图*/            for(int i=head[u];~i;i=e[i].next){                int v=e[i].to;                if(f[u]!=f[v]){                    deg[f[v]]++;                    add1(f[u],f[v]);                }            }        }        int Max=-1;        for(int i=1;i<=ans;i++)            if(deg[i]==0)                Max=max(Max,dfs(i));        printf("%d\n",Max);    }}

阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 电气没考上国网怎么办 小区宽带业务被个人承包怎么办 高铁用户名忘了怎么办 昆山社保号是8位怎么办 高铁票误了时间怎么办 动车票没赶上车怎么办 铁路用户名已存在要怎么办 铁路12306用户名忘了怎么办 铁路12306的用户名忘了怎么办 铁路12306注册名已存在怎么办 12306账号密码忘记了怎么办 12306登录名忘记了怎么办 电脑系统崩溃开不了机怎么办 高铁车票没赶上怎么办 机票错点了退票怎么办 快递号码留错了怎么办 物流号码留错了怎么办 12306身份信息被注册怎么办 12306注册身份信息重复怎么办 12306账号被注册了怎么办 高铁账号忘记了怎么办 铁路12306网站密码错误怎么办 网上买火车票密码忘了怎么办 快递没收到点了确认收货怎么办 快递没收到自动确认收货怎么办 房地产股市汇率一齐暴跌怎么办 尼日利亚落地签过期了怎么办 期货亏光了所有怎么办 期货钱亏完了该怎么办 做黄金亏损500万怎么办 炒黄金被骗35万怎么办 淘宝发货填错单号怎么办 发货单号填错了怎么办 发快递忘了单号怎么办 国际物流查不到物流怎么办 纸币上印邪教该怎么办 钥匙掉到电梯缝里怎么办 汽车电子钥匙铜线折一根怎么办 防盗门的锁不好开怎么办 同学帮刷饭卡说不用还钱了怎么办 em231电源指示灯不亮怎么办