ZOJ3795 Grouping 強連通縮點+圖的最長路

來源:互聯網
上載者:User

標籤:style   blog   color   2014   os   for   

給出m條a年齡大於等於b的資訊,要求可以比較的兩個人不能放在同一組,問最少能分成幾組。

由於是大於等於,所以原圖可能構成強連通分量,意思就是有很多人年齡相同(想想也該知道,總共10w個人,肯定有很多人年齡重複= =!)將原圖縮點後,對新圖記憶化搜尋求最長路。

如果不縮點,會RE。。。

#include <iostream>#include<cstring>#include<cstdio>#include<string>#include<algorithm>using namespace std;#define MAXN 100005#define MAXM 300005struct node{    int to,next;}edge[MAXM],edge2[MAXM];int head[MAXN],en;int low[MAXN],dfn[MAXN],stack[MAXN],top,set[MAXN],col,num;bool vis[MAXN],instack[MAXN];int n;int m;void addedge(int a,int b){    edge[en].to=b;    edge[en].next=head[a];    head[a]=en++;}void tarjan(int u){    vis[u]=1;    dfn[u]=low[u]=++num;    instack[u]=true;    stack[++top]=u;    for(int i=head[u];i!=-1;i=edge[i].next)    {        int v=edge[i].to;        if(!vis[v])        {            tarjan(v);            low[u]=min(low[u],low[v]);        }        else            if(instack[v])                low[u]=min(dfn[v],low[u]);    }    if(dfn[u]==low[u])    {        int j;        col++;        do        {            j=stack[top--];            instack[j]=false;          set[j]=col;        }        while (j!=u);    }}int head2[MAXN];int sum[MAXN],en2;int dp[MAXN];int in[MAXN];void init(){    int i;    en2=en=top=col=num=0;    memset(dp,-1,sizeof(dp));    memset(head,-1,sizeof(head));    memset(instack,0,sizeof(instack));    memset(vis,0,sizeof(vis));    memset(set,-1,sizeof(set));    memset(head2,-1,sizeof(head2));    memset(sum,0,sizeof(sum));    memset(in,0,sizeof(in));}void addedge2(int a,int b){    edge2[en2].to=b;    edge2[en2].next=head2[a];    head2[a]=en2++;}int dfs(int now){    if(~dp[now]) return dp[now];    int maxn=sum[now];    for(int i=head2[now];~i;i=edge2[i].next)    {        int to=edge2[i].to;        maxn=max(maxn,sum[now]+dfs(to));    }    return dp[now]=maxn;}int main(){    int a,b;    while(~scanf("%d%d",&n,&m))    {        init();        for(int i=1;i<=m;i++)        {            scanf("%d%d",&a,&b);            addedge(a,b);        }        for(int i=1;i<=n;i++)            if(!vis[i])tarjan(i);        for(int i=1;i<=n;i++) sum[set[i]]++;     //   for(int i=1;i<=n;i++) printf("%d=%d\n",i,set[i]);        for(int i=1;i<=n;i++)        {            for(int j=head[i];~j;j=edge[j].next)            {                int to=edge[j].to;                if(set[to]!=set[i])                {                    in[set[to]]++;                    addedge2(set[i],set[to]);                }            }        }        for(int i=1;i<=col;i++) if(in[i]==0) addedge2(0,i);        dfs(0);        int ans=0;        for(int i=1;i<=col;i++) ans=max(ans,dp[i]);        printf("%d\n",ans);    }    return 0;}/*7 81 22 33 13 53 44 66 77 4*/


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.