zoukankan      html  css  js  c++  java
  • Hawk-and-Chicken 强连通

      题意:一群人投票  票具有传递性  求出累计和最大的数和 哪几个人最大

    强连通好题!!!

    毫无疑问先强连通缩点

    一开始打算拓扑排序求dis  但是发现拓扑排序会有重复累加的情况

    那么就反向建图   当出点为0时  进行dfs搜索cnt

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s)
    #define ll long long
    #define pb push_back
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    const int N=50000+5;
    int head[N*6],pos;
    vector<int> mp[N];
    struct Edge
    {
        int to,nex;
    }edge[N*6];
    void add(int a,int b)
    {
        edge[++pos].nex=head[a];
        head[a]=pos;
        edge[pos].to=b;
    }
    int ind,tot,cnt,dfn[N],low[N],vis[N],belong[N],Stack[N],num[N],in[N],dis[N],out[N];
    void init()
    {
        ind=tot=pos=cnt=0;
        CLR(Stack,0);
        CLR(out,0);
        CLR(dis,0);
        CLR(in,0);
        CLR(num,0);
        CLR(dfn,0);
        CLR(low,0);
        CLR(vis,0);
        CLR(head,0);
    }
    void tarjan(int x)
    {
        dfn[x]=low[x]=++tot;
        Stack[++ind]=x;
        vis[x]=1;
        for(int i=head[x];i;i=edge[i].nex)
        {
            int v=edge[i].to;
            if(!dfn[v])
            {
                tarjan(v);
                low[x]=min(low[x],low[v]);
            }
            else if(vis[v])
                low[x]=min(low[x],low[v]);
    
        }
        if(low[x]==dfn[x])
        {
            cnt++;int v;
            do
            {
                v=Stack[ind--];
                vis[v]=0;
                num[cnt]++;
                belong[v]=cnt;
            }
            while(v!=x);
        }
    }
    int Cnt;
    void dfs(int x)
    {
        Cnt+=num[x];
        if(mp[x].size())
        rep(i,0,mp[x].size()-1)
        {
            int v=mp[x][i];
            if(vis[v])continue;
            vis[v]=1;
            dfs(v);
        }
    }
    
    int main()
    {
        int cas;
        RI(cas);
        int T=0;
        while(cas--)
        {
            init();
            int n,m;
            RII(n,m);
            rep(i,1,m)
            {
                int a,b;
                RII(a,b);
                a++;b++;
                add(a,b);
            }
    
        rep(i,1,n)
        if(!dfn[i])tarjan(i);
    
        rep(i,1,n)
        {
            int u=belong[i];
            for(int j=head[i];j;j=edge[j].nex)
            {
                int v=belong[ edge[j].to ];
    
                if(u!=v)
                    in[v]++,mp[v].pb(u),out[u]++;
            }
        }
        int maxx=0;
    
        rep(i,1,cnt)
        if(out[i]==0)
        {
            Cnt=0;
            CLR(vis,0);
            dfs(i);
            dis[i]=Cnt;
    
            if(Cnt>maxx)
            {
                maxx=Cnt;
            }
        }
        rep(i,1,cnt)
        maxx=max(maxx,dis[i]);
    
        printf("Case %d: %d
    ",++T,maxx-1);
        int first=1;
        rep(i,1,n)
        {
            int u=belong[i];
            if(dis[u]==maxx)
            {
                if(first)
                    first=0,printf("%d",i-1);
                else printf(" %d",i-1);
            }
        }
        cout<<endl;
        rep(i,1,cnt)
        mp[i].clear();
        }
        return 0;
    
    }
    View Code
  • 相关阅读:
    C#中如何禁止WindowsMediaPlayer双击全屏显示
    .NET中的泛型概述
    c# Windows服务管理
    C:Program不是内部或外部命令,也不是可运行的程序或批处理文件。
    Wireshark教程之二:Wireshark捕获数据分析
    Wireshark教程之一:认识Wireshark界面
    利用windows服务实现整点报时功能
    在windows服务中使用定时器
    flickity:支持触摸滑动,响应迅速的幻灯片轮播插件
    无法定位 Local Database Runtime 安装。请验证 SQL Server Express 是否正确安装以及本地数据库运行时功能是否已启用。
  • 原文地址:https://www.cnblogs.com/bxd123/p/10799371.html
Copyright © 2011-2022 走看看