HDOJ 3639 Hawk-and-Chicken

来源:互联网 发布:傲剑神照经升级数据 编辑:程序博客网 时间:2024/05/16 07:51

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3639


此题可能拿到的时候很容易想到直接深搜可能就能解决,但是实际上不行,如果要深搜的话,那我们必须要满足一个条件,那就是不能成环,但是这个题显然是可能有成环的(如样例2),那怎么办呢,这时候我们可以去借助强连通分量来解决这个问题,因为如果我们用Tarjan算法把所有的强连通找到后,再讲所有强连通分量缩点处理后,每个点就满足不会成环的性质,我们就可以进行DFS深搜了,当然在这之前还得反向建图求入度(可以不用反向建图求出度),所以总结此题就是强连通+缩点+反向构图+DFS。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <stack>#include <vector>#define MAXN 5010 using namespace std; vector<int> g[MAXN],g2[MAXN];stack<int> st; int n,index,num,dfn[MAXN],low[MAXN],belong[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();            belong[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(belong[i] != belong[g[i][j]])                 {                    g2[belong[g[i][j]]].push_back(belong[i]);                    in[belong[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[belong[i]] == maxans)             {                 if(!flag){                printf("%d", i);                 flag=1;                 }                else printf(" %d",i);             }        printf("\n");     }    return 0; }




0 0
原创粉丝点击