UVA 11324 The Largest Clique(tarjan有向图强连通+缩点)

来源:互联网 发布:iphone移动数据怎么关 编辑:程序博客网 时间:2024/04/30 03:28

题意:给出一个有向图,问最多能有多少点能构成一个集合,这个集合性质是任意两点能相互到达,即u->v or v->y.

分析:任意两点能互相到达,而且是有向图,很容易想到是强连通。要使这个集合中的点最多,仅一个强连通分量肯定不行,可由多个强连通分量构成. 那么求出各个强连通分量后,缩点,然后深搜一次,找出最大点集。

#include <iostream>#include <stdio.h>#include <math.h>#include <algorithm>#include <queue>#include <stack>#include <vector>#include <string>#include <string.h>#include <map>#include <set>using namespace std;#define maxn 2002#define inff 0x3FFFFFFFint dfn[maxn],low[maxn],vis[maxn],succ[maxn],bic[maxn];stack<int>sta;vector<int>E[100000];int tim,ans,maxx,cnt;struct node{    int en,next;}edge[100000];int p[maxn],num;void init(){    num=0;    memset(p,-1,sizeof(p));}void add(int st,int en){    edge[num].en=en;    edge[num].next=p[st];    p[st]=num++;}void tarjan(int u,int fa){    low[u]=dfn[u]=++tim;    vis[u]=1;    sta.push(u);    int j,v;    for(j=p[u];j+1;j=edge[j].next)    {        v=edge[j].en;//        if(v==fa)continue;//不判断父亲节点比如 1->2,2->1 他们在一个连通块        if(!dfn[v])        {            tarjan(v,u);            low[u]=min(low[u],low[v]);        }        else            if(vis[v])                low[u]=min(low[u],dfn[v]);    }    if(low[u]==dfn[u])    {        cnt++;        while(!sta.empty())        {            int x=sta.top();            sta.pop();            succ[x]=cnt;            vis[x]=0;            if(x==u)break;        }    }}void dfs(int i,int temp){    int j;    int len=E[i].size();     temp+=bic[i];     ans=max(ans,temp);    for(j=0;j<len;j++)    {        int v=E[i][j];      dfs(v,temp);    }}int main(){    int n,m,i,t,j;    cin>>t;    while(t--)    {        cin>>n>>m;        if(n==0){cout<<0<<endl;continue;}        init();        for(i=1;i<=m;i++)        {            int a,b;            cin>>a>>b;            add(a,b);        }        memset(low,0,sizeof(low));        memset(dfn,0,sizeof(dfn));        memset(vis,0,sizeof(vis));        memset(bic,0,sizeof(bic));        tim=0;cnt=0;        while(!sta.empty())sta.pop();        for(i=1;i<=n;i++)        {            if(!dfn[i])            {                tarjan(i,-1);            }        }        for(i=1;i<=n;i++)        {            bic[succ[i]]++;        }        for(i=0;i<100000;i++)E[i].clear();        for(i=1;i<=n;i++)        {            for(j=p[i];j!=-1;j=edge[j].next)            {                int v=edge[j].en;                if(succ[i]!=succ[v])                    E[succ[i]].push_back(succ[v]);            }        }        ans=0;        for(i=1;i<=cnt;i++)        {           dfs(i,0);        }        cout<<ans<<endl;    }    return 0;}


0 0
原创粉丝点击