Hawk-and-Chicken 强连通
阅读原文时间:2023年07月10日阅读:2

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

强连通好题!!!

毫无疑问先强连通缩点

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

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

#include
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=+;
int head[N*],pos;
vector mp[N];
struct Edge
{
int to,nex;
}edge[N*];
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=;
CLR(Stack,);
CLR(out,);
CLR(dis,);
CLR(in,);
CLR(num,);
CLR(dfn,);
CLR(low,);
CLR(vis,);
CLR(head,);
}
void tarjan(int x)
{
dfn[x]=low[x]=++tot;
Stack[++ind]=x;
vis[x]=;
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\]=;  
        num\[cnt\]++;  
        belong\[v\]=cnt;  
    }  
    while(v!=x);  
}  

}
int Cnt;
void dfs(int x)
{
Cnt+=num[x];
if(mp[x].size())
rep(i,,mp[x].size()-)
{
int v=mp[x][i];
if(vis[v])continue;
vis[v]=;
dfs(v);
}
}

int main()
{
int cas;
RI(cas);
int T=;
while(cas--)
{
init();
int n,m;
RII(n,m);
rep(i,,m)
{
int a,b;
RII(a,b);
a++;b++;
add(a,b);
}

rep(i,,n)  
if(!dfn\[i\])tarjan(i);

rep(i,,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=;

rep(i,,cnt)  
if(out\[i\]==)  
{  
    Cnt=;  
    CLR(vis,);  
    dfs(i);  
    dis\[i\]=Cnt;

    if(Cnt>maxx)  
    {  
        maxx=Cnt;  
    }  
}  
rep(i,,cnt)  
maxx=max(maxx,dis\[i\]);

printf("Case %d: %d\\n",++T,maxx-);  
int first=;  
rep(i,,n)  
{  
    int u=belong\[i\];  
    if(dis\[u\]==maxx)  
    {  
        if(first)  
            first=,printf("%d",i-);  
        else printf(" %d",i-);  
    }  
}  
cout<<endl;  
rep(i,,cnt)  
mp\[i\].clear();  
}  
return ;

}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章