zoj3795 Grouping --- 強連通,求最長路

來源:互聯網
上載者:User

標籤:blog   http   os   art   問題   演算法   

給定圖,求把至少把圖拆成幾個集合能夠使集合內的點沒有直接或間接關係。

首先由題意可得圖中可能含環,而環裡面的點肯定是要拆開的。

縮點建圖得DAG圖,可以想象一下。。把圖從入度為零的點向下展開,位於同一層的點放在一個集合是沒有關係的,

那麼題目所求的問題就轉化成求圖中最長路的問題了。


這個題的實質和 這題 其實是一模一樣的。。


#include <iostream>#include <cstring>#include <string>#include <cstdio>#include <cmath>#include <algorithm>#include <vector>#include <queue>#include <map>#define inf 0x3f3f3f3f#define eps 1e-6#define ll __int64#define M 100010//圖中點數using namespace std;int sta[M],top;          //Tarjan 演算法中的棧bool vis[M];             //檢查是否在棧中int dfn[M];                  //深度優先搜尋訪問次序int low[M];                  //能追溯到的最早的次序int ccnt;                //有向圖強連通分量個數int id;                 //索引號vector<int> e[M];        //鄰接表表示vector<int> part[M];   //獲得強連通分量結果int inpart[M];   //記錄每個點在第幾號強連通分量裡int degree[M];     //記錄每個強連通分量的度vector<int> edge[M];//縮點後建圖int ans,n,m,dp[M],in[M],point[M];void tarjan(int x){    int i,j;    dfn[x]=low[x]=id++;    vis[x]=1;    sta[++top]=x;    for(i=0;i<e[x].size();i++)    {        j=e[x][i];        if(dfn[j]==-1)        {            tarjan(j);            low[x]=min(low[x],low[j]);        }        else if(vis[j])            low[x]=min(low[x],dfn[j]);    }    if(dfn[x]==low[x])    {        do        {            j=sta[top--];            vis[j]=0;            part[ccnt].push_back(j);            inpart[j]=ccnt;            point[ccnt]++;        }while(j!=x);        ccnt++;    }}void solve(int n){    memset(sta,-1,sizeof sta);    memset(vis,0,sizeof vis);    memset(dfn,-1,sizeof dfn);    memset(low,-1,sizeof low);    memset(point,0,sizeof point);    top=ccnt=id=0;    for(int i=1;i<=n;i++)        if(dfn[i]==-1)            tarjan(i);}int dfs(int x){    if(dp[x]) return dp[x];    dp[x]=point[x];    int i;    for(i=0;i<edge[x].size();i++)    {        int tmp=edge[x][i];        dp[x]=max(dp[x],point[x]+dfs(tmp));    }    return dp[x];}int main(){    int n,m,i,j,a,b;    while(~scanf("%d%d",&n,&m))    {        for(i=0;i<=n;i++)        {            part[i].clear();            e[i].clear();            edge[i].clear();        }        while(m--)        {            scanf("%d%d",&a,&b);            e[a].push_back(b);        }        solve(n);        memset(in,0,sizeof in);        for(i=1;i<=n;i++)//枚舉原圖中的邊        {            for(j=0;j<e[i].size();j++)            {                int a=inpart[i];                int b=inpart[e[i][j]];//                if(a!=b)                {                    in[b]++;                    edge[a].push_back(b);                }            }        }        ans=0;        memset(dp,0,sizeof dp);        for(i=0;i<ccnt;i++)//縮點後的圖上是從0到ccnt編號的        {            if(!in[i])                ans=max(ans,dfs(i));        }        printf("%d\n",ans);    }    return 0;}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.