• BZOJ 1051 & 强联通分量


    题意:

      怎么说呢...这种题目有点概括不来....还是到原题面上看好了...

    SOL:

      求出强联通分量然后根据分量重构图,如果只有一个点没有出边那么就输出这个点中点的数目.

      对就是这样.

      哦还有论边双与强联通的tarjan的不同...边双要记录边...无向图的边有两条要判断是不是一条...还有什么不同呢...我也不造了...看起来很像很好写就对了...

    Code:

      

    /*==========================================================================
    # Last modified: 2016-03-13 19:24
    # Filename: 1051.cpp
    # Description: 
    ==========================================================================*/
    #define me AcrossTheSky 
    #include <cstdio> 
    #include <cmath> 
    #include <ctime> 
    #include <string> 
    #include <cstring> 
    #include <cstdlib> 
    #include <iostream> 
    #include <algorithm> 
      
    #include <set> 
    #include <map> 
    #include <stack> 
    #include <queue> 
    #include <vector> 
     
    #define lowbit(x) (x)&(-x) 
    #define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++) 
    #define FORP(i,a,b) for(int i=(a);i<=(b);i++) 
    #define FORM(i,a,b) for(int i=(a);i>=(b);i--) 
    #define ls(a,b) (((a)+(b)) << 1) 
    #define rs(a,b) (((a)+(b)) >> 1) 
    #define getlc(a) ch[(a)][0] 
    #define getrc(a) ch[(a)][1] 
     
    #define maxn 100000 
    #define maxm 100000 
    #define pi 3.1415926535898 
    #define _e 2.718281828459 
    #define INF 1070000000 
    using namespace std; 
    typedef long long ll; 
    typedef unsigned long long ull; 
     
    template<class T> inline 
    void read(T& num) { 
        bool start=false,neg=false; 
        char c; 
        num=0; 
        while((c=getchar())!=EOF) { 
            if(c=='-') start=neg=true; 
            else if(c>='0' && c<='9') { 
                start=true; 
                num=num*10+c-'0'; 
            } else if(start) break; 
        } 
        if(neg) num=-num; 
    } 
    /*==================split line==================*/
    struct Edge{
    	int to,next;
    }e[maxm],d[maxm];
    int head[maxm],first[maxn];
    int low[maxn],dfn[maxn],s[maxn],belong[maxn],in[maxn],sz[maxn];
    bool instack[maxn];
    int sume=1,scc,clo=0,top=0,n,m;
    void addedge(int x,int y){
    	sume++; e[sume].to=y; e[sume].next=first[x]; first[x]=sume;
    }
    void tarjan(int u){
    	dfn[u]=low[u]=(++clo);
    	s[++top]=u;
    	instack[u]=true;
    	for (int i=first[u];i;i=e[i].next){
    		int y=e[i].to;
    		if (!dfn[y]){
    			tarjan(y);
    			low[u]=min(low[u],low[y]);
    		}
    		else if (instack[y]) low[u]=min(dfn[y],low[u]);
    	}
    	if (low[u]==dfn[u]){
    		scc++;
    		while (true){
    			int v=s[top--];
    			belong[v]=scc;
    			instack[v]=false;
    			sz[scc]++;
    			if (v==u) break;
    		}
    	}
    }
    void rebuild(){
    	int cnt=0;
    	FORP(i,1,n){
    		for (int j=first[i];j;j=e[j].next){
    			int v=e[j].to;
    			if (belong[i]!=belong[v]){
    				//----------addedge
    				cnt++;
    				d[cnt].to=belong[v];
    				d[cnt].next=head[belong[i]];
    				head[belong[i]]=cnt;
    				//---------------------*/
    			}
    		}
    	}
    }
    int main(){ 
    	read(n); read(m);
    	FORP(i,1,m){
    		int x,y;
    		read(x); read(y);
    		addedge(x,y);
    	}
    	memset(dfn,0,sizeof(dfn));
    	FORP(i,1,n) if (!dfn[i]) tarjan(i);
    	rebuild();
    	int ans=0;
    	FORP(i,1,scc) if (!head[i]) {
    		if (ans) {printf("%d",0); return 0;}
    		else ans=sz[i];
    	}
    	printf("%d",ans);
    	return 0;
    }
    
    Sometimes it s the very people who no one imagines anything of. who do the things that no one can imagine.
  • 相关阅读:
    排序算法-总览
    MySQL插入大批量测试数据
    【剑指offer】面试的流程
    并发编程-内置锁
    并发编程-使用线程安全类
    规约先行-(二十一)设计规约
    规约先行-(二十)服务器
    [转]web.xml什么时候被加载进内存的
    DOM和BOM的理解
    代理&反向代理
  • 原文地址:https://www.cnblogs.com/YCuangWhen/p/5273011.html
Copyright © 2020-2023  润新知