hdu 3639 Hawk-and-Chicken

http://acm.hdu.edu.cn/showproblem.php?pid=3639 

题意:给一个无向图,求出拥有最多祖父的节点。

思路:先tarjan缩点,可以知道只能出现在叶子节点,所以反向建图,对每个入度为0的节点进行遍历统计。

View Code
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<bitset>
#include<stack>
#include<utility>
using namespace std;
const int maxn = 5005;
struct nd
{
        int u,v,next;
}edge[maxn*10];
int head[maxn],vis[maxn],dfn[maxn],low[maxn],belong[maxn],c[maxn],as[maxn],in[maxn];
stack<int>st;
bitset<maxn>Bit;
int ecnt,cnt,idx,tot;
void add(int u,int v)
{
        edge[ecnt].u = u;
        edge[ecnt].v = v;
        edge[ecnt].next = head[u];
        head[u] = ecnt++;
}
void tarjan(int u)
{
        int i,v;
        dfn[u] = low[u] = ++idx;
        vis[u] = 1;
        st.push(u);
        for(i = head[u]; i != -1; i = edge[i].next)
        {
                v = edge[i].v;
                if(!dfn[v]){
                        tarjan(v);
                        low[u] = min(low[v],low[u]);
                }else if(vis[v]) low[u] = min(dfn[v],low[u]);
        }
        if(dfn[u]==low[u])
        {
                ++cnt;
                do{
                        v = st.top();
                        st.pop();
                        vis[v] = 0;
                        c[cnt]++;
                        belong[v] = cnt;
                }while(v!=u);
        }
}
void dfs(int rt,int u,int sum)
{
        int i,v;
        if(Bit[u])return;
        Bit[u] = 1;
        as[rt] += sum;
        for(i = head[u]; i != -1; i = edge[i].next)
        {
                v = edge[i].v;
                dfs(rt,v,c[v]);
        }

}
int main()
{
        int i,j,k,t,n,m,u,v,ans,cas = 0;
        scanf("%d",&t);
        while(t--)
        {
                scanf("%d %d",&n,&m);
                memset(vis,0,sizeof(vis));
                memset(dfn,0,sizeof(dfn));
                memset(belong,0,sizeof(belong));
                memset(c,0,sizeof(c));
                memset(as,0,sizeof(as));
                memset(in,0,sizeof(in));
                memset(head,-1,sizeof(head));
                ecnt = cnt = idx = 0;
                for(i = 0; i < m; ++ i)
                {
                        scanf("%d %d",&u,&v);
                        add(u,v);
                }
                for(i = 0; i < n; ++ i) if(!dfn[i]) tarjan(i);
                memset(head,-1,sizeof(head));
                k = ecnt; ecnt = 0;
                for(i = 0; i < k; ++ i)
                {
                        u = belong[edge[i].u];
                        v = belong[edge[i].v];
                        if(u!=v){ add(v,u); in[u]++; }
                }
                ans = 0;
                for(i = 1; i <= cnt; ++ i)if(!in[i])
                {
                        Bit.reset();
                        dfs(i,i,c[i]);
                        ans = max(ans,as[i]);
                }
                k = 0;
                for(i = 0; i < n; ++ i) if(as[belong[i]]==ans) c[k++] = i;
                printf("Case %d: %d\n",++cas,ans-1);
                for(i = 0; i < k - 1; ++i) printf("%d ",c[i]);printf("%d\n",c[i]);
        }return 0;
}

posted on 2012-07-03 10:20  aigoruan  阅读(156)  评论(0)    收藏  举报

导航