zoukankan      html  css  js  c++  java
  • P2341 [HAOI2006]受欢迎的牛

    题目地址


    简述:

    • 缩点+判定(性质)

    易错点:

    • 缩点后是一个DAG图,那么是明星的点一定不会向其他点连边。 那么就可以判断每个点的出度是否为0,并统计是否只有一个点出度为0.

    #include<cstdio>
    #include<iostream>
    #include<vector>
    #include<queue>
    using namespace std;
    const int MAXN=1000010,MAXM=1000010;
    struct first_Edge{
    	int from,to,nxt;
    }first_e[MAXM];
    int first_head[MAXN],first_edgeCnt=1;
    void addFirstEdge(int u,int v){
    	first_e[++first_edgeCnt].from=u;
    	first_e[first_edgeCnt].to=v;
    	first_e[first_edgeCnt].nxt=first_head[u];
    	first_head[u]=first_edgeCnt;
    }
    int dfn[MAXN],dfnCnt=0,low[MAXN];
    bool inc[MAXN];
    int stck[MAXN],top=0;
    vector<int> scc[MAXN];
    int sccCnt=0,c[MAXN],siz[MAXN];
    void tarjan(int x){
    	low[x]=dfn[x]=++dfnCnt;
    	stck[++top]=x;
    	inc[x]=1;
    	for(int i=first_head[x];i;i=first_e[i].nxt){
    		int v=first_e[i].to;
    		if(!dfn[v]){
    			tarjan(v);
    			low[x]=min(low[x],low[v]);
    		}else if(inc[v])low[x]=min(low[x],dfn[v]);
    	}
    	if(low[x]==dfn[x]){
    		int y;sccCnt++;
    		do{
    			y=stck[top--];
    			inc[y]=0; 
    			scc[sccCnt].push_back(y);
    			c[y]=sccCnt;
    			siz[sccCnt]+=1;
    		}while(x!=y);
    	}
    }
    struct second_Edge{
    	int from,to,nxt;
    }second_e[MAXM];
    int second_head[MAXN],second_edgeCnt=0;
    void addSecondEdge(int u,int v){
    	second_e[++second_edgeCnt].from=u;
    	second_e[second_edgeCnt].to=v;
    	second_e[second_edgeCnt].nxt=second_head[u];
    	second_head[u]=second_edgeCnt;
    }
    int cd[MAXN];
    void rebuild(){
    	for(int i=1;i<=first_edgeCnt;i++){
    		int nowU,nowV;
    		nowU=first_e[i].from,nowV=first_e[i].to;
    		if(c[nowU]!=c[nowV]){
    			addSecondEdge(c[nowU],c[nowV]);
    			cd[c[nowU]]++;
    		}
    	}
    }
    int main(){
    	int n,m;
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++){
    		int a,b;
    		scanf("%d%d",&a,&b);
    		addFirstEdge(a,b);
    	}
    	for(int i=1;i<=n;i++)
    		if(!dfn[i])tarjan(i);
    	rebuild();
    	int ans=0;
    	bool isHave=0;
    	for(int i=1;i<=sccCnt;i++){
    		if(!cd[i]){
    			ans=scc[i].size();
    			if(isHave){
    				cout<<0<<endl;
    				return 0;
    			}
    			isHave=1;
    		}
    	}
    	cout<<ans<<endl;
    	return 0;
    }
  • 相关阅读:
    Selenium python 常用定位方法
    第四周总结
    python自然语言处理——提取关键词,标签
    python 调用百度地图api接口获取地理详细信息行政代码等
    python分词技术——jieba安装使用
    质量属性战术--6.易用性战术
    Kettle的使用——大数据清洗技术
    周总结2
    DataX的使用——大数据同步技术
    python编程:从入门到实践
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680601.html
Copyright © 2011-2022 走看看