tjut 3639

来源:互联网 发布:爱奇艺用户数据分析 编辑:程序博客网 时间:2024/06/01 09:34
#include<iostream>#include<algorithm>#include<stack>#include<vector>#define MAXN 5010 using namespace std; vector<int> g[MAXN],g2[MAXN];//g保存原图,g2保存缩点反向后的图stack<int> st; int n,index,num,dfn[MAXN],low[MAXN],f[MAXN]; bool vis[MAXN],instack[MAXN]; int ans[MAXN],in[MAXN],scc[MAXN],sum; void tarjan(int u)//求强连通分支{     int v;     dfn[u] = low[u] = index++;      st.push(u);    instack[u] = true;     vis[u] = true;     for(int i=0; i<g[u].size(); i++)     {        v = g[u][i];          if(!vis[v])         {                      tarjan(v);                   low[u] = min(low[u], low[v]);              }            else if(instack[v])             low[u] = min(low[u], dfn[v]);      }     if(dfn[u] == low[u])     {                 do         {                 v = st.top();                    instack[v] = false;             st.pop();            f[v]=num;//记录每一个点所在的强连通分支 scc[num]++;//保存该强连通分支的点数 }         while(v != u);         num++;    }}void dfs(int u)//深搜求出可到达该连通分支的点数{     vis[u]=true;     sum+=scc[u];    for(int i=0;i<g2[u].size();i++)         if(!vis[g2[u][i]])             dfs(g2[u][i]);}int main() {    int T,m,a,b,cas=0;     scanf("%d",&T);     while(T--)     {        scanf("%d %d",&n,&m);         for(int i=0;i<=n;i++)//注意要将向量清空 {             g[i].clear();            g2[i].clear();        }        while(m--)         {            scanf("%d %d",&a,&b);             g[a].push_back(b);        }        index=num=0;         memset(vis,false,sizeof(vis));         memset(instack,false,sizeof(instack));         memset(scc,0,sizeof(scc));         for(int i=0;i<n;i++)         {            if(!vis[i])                 tarjan(i);        }        memset(in,0,sizeof(in));         for(int i=0;i<n;i++)//重新构图 for(int j=0;j<g[i].size();j++)             {                if(f[i]!=f[g[i][j]])                 {                    g2[f[g[i][j]]].push_back(f[i]);                    in[f[i]]++;                 }            }        int maxans=-1;         memset(ans,-1,sizeof(ans));         printf("Case %d: ",++cas);         for(int i=0;i<num;i++)         {            if(in[i]==0)             {                sum=0;                 memset(vis,false,sizeof(vis));                 dfs(i);                ans[i]=sum;                if(sum>maxans)                     maxans=sum;            }        }        printf("%d\n",maxans-1);         int flag=0;         for (int i = 0; i < n; i++)             if ( ans[f[i]] == maxans)             {                 if(!flag){                 printf("%d", i);                 flag=1;                 }                else printf(" %d",i);             }        printf("\n");     }    return 0; }

0 0
原创粉丝点击