zoukankan      html  css  js  c++  java
  • BZOJ 1051 HAOI 2006 受欢迎的牛

    【题解】

      先用tarjan缩点,然后如果某个强联通分量的出度为0,则该强联通分量内的点数为答案,否则无解。因为若其他所有的强联通分量都有边连向Ai,则Ai必定没有出边,否则Ai连向的点所属的强联通分量也属于Ai。

      

    #include<cstdio>
    #include<algorithm>
    #define N (50010)
    #define rg register
    using namespace std;
    int n,m,tot,top,color,ans,last[N],st[N],col[N],dfn[N],low[N],num[N];
    int degree_out[N];
    struct edge{
    	int to,pre;
    }e[N];
    struct record{
    	int u,v;
    }r[N];
    inline int read(){
    	int k=0,f=1; char c=getchar();
    	while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    	while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
    	return k*f;
    }
    inline int min(int x,int y){return x<y?x:y;}
    inline void add(int x,int y){e[++tot]=(edge){y,last[x]}; last[x]=tot;}
    void tarjan(int x){
    	dfn[x]=low[x]=++tot; st[++top]=x;
    	for(rg int i=last[x],to;i;i=e[i].pre)
    		if(!dfn[to=e[i].to]) tarjan(to),low[x]=min(low[x],low[to]);
    		else if(!col[to]) low[x]=min(low[x],dfn[to]);
    	if(dfn[x]==low[x])
    		for(color++;st[top+1]!=x;top--) col[st[top]]=color,num[color]++;
    }
    int main(){
    	n=read(); m=read();
    	for(rg int i=1,u,v;i<=m;i++) u=read(),v=read(),add(u,v),r[i].u=u,r[i].v=v;
    	tot=0;
    	for(rg int i=1;i<=n;i++) if(!col[i]) tarjan(i);
    	for(rg int i=1,u,v;i<=m;i++){
    		u=r[i].u; v=r[i].v;
    		if(col[u]!=col[v]) degree_out[col[u]]++;
    	}
    	int ans=-1;
    	for(rg int i=1;i<=color;i++) if(!degree_out[i]){
    		printf("%d
    ",num[i]);
    		return 0;
    	}
    	puts("0");
    	return 0;
    }
    

      

  • 相关阅读:
    【Qt】无边框窗体中带有ActiveX组件时的一个BUG
    Qt:正确判断文件、文件夹是否存在的方法
    自定义Data Service Providers
    Facebook的ATOM Editor的底层Electron
    ASP.NET Web API中使用OData
    Oracle 使用
    ODP.NET 之访问 Oracle 数据库
    Oracle安装及使用入门
    架构设计
    CQRS模式实现
  • 原文地址:https://www.cnblogs.com/DriverLao/p/8407091.html
Copyright © 2011-2022 走看看