P1726 上白泽慧音

来源:互联网 发布:手机淘宝秒杀软件下载 编辑:程序博客网 时间:2024/06/05 08:26

luogu——————

解法:
一个绝对连通区域就是一个强连通分量
因为题目要求输出最大强连通分量的规模,所以不需要考虑重边的问题(即会出现大包小的情况),如果要输出教学区的个数,则需要减去此种情况

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>using namespace std;int num[2*50009],head[5009],nxt[2*50009],fig[5009],mc=-1,cnt=0; int n,m,dfs_num=0,dfn[5009],low[5009],color_num=0,color[5009],st[5009],kk;bool vis[5009];int top=0;void Tarjan(int x){    dfn[x]=++dfs_num;    low[x]=dfs_num;    vis[x]=true;    st[++top]=x;    for(int i=head[x];i;i=nxt[i])    {        int k=num[i];        if(!dfn[k])        {            Tarjan(k);            low[x]=min(low[x],low[k]);        }        else if(vis[k]) low[x]=min(dfn[k],low[x]);    }    if(low[x]==dfn[x])    {        vis[x]=false;        color[x]=++color_num;        int t=1;        while(st[top]!=x)        {            vis[st[top]]=false;            color[st[top]]=color_num;            top--;t++;        }        top--;        fig[color_num]=t;        if(t>mc){//记录点最多的强连通分量里点的个数             mc=t;            kk=color_num;//记录点最多的强连通分量的代号         }    }}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++)    {        int a,b,t;        scanf("%d%d%d",&a,&b,&t);        cnt++;        num[cnt]=b;        nxt[cnt]=head[a];        head[a]=cnt;        if(t==2)        {            cnt++;            num[cnt]=a;            nxt[cnt]=head[b];            head[b]=cnt;        }    }    for(int i=1;i<=n;i++)    {        if(!dfn[i]) Tarjan(i);    }    printf("%d\n",mc);//    for(int i=1;i<=n;i++)    {        if(color[i]==kk)//输出强连通分量里的点         printf("%d ",i);    }    return 0;}
1 0