CCF CSP 201509 - 4 고속도로 [Kosaraju]

13795 단어 CCFCSP인증
제목:
  • N 개의 점, M 개의 변 에 방향 그림 이 있 고 몇 쌍 (x, y) (x, y) (x, y) 이 x x x 에서 y y 까지 만족 할 수 있 으 며 y y 에서 x x x x x x x x x 까지 도 가능 하 다
  • .
    생각:
  • S C SCC SCC 중 점 만 이 두 가지 가 달 할 수 있 는 성질
  • 을 만족시킨다.
  • K o s a r a j u Kosaraju Kosaraju 알고리즘 으로 그림 속 의 모든 S C SCC SCC SCC 를 찾 아 그 중의 정점 대수
  • 를 계산한다.
  • s i z e [i] size [i] size [i] 를 i 번 째 s c scc scc 중점 의 개수 로 설정 하면 a n s + = s i z e [i] ∗ 8727; (s i z e [i] − 1) / 2 ans + = size [i] * (size [i] - 1) / 2 ans + = size [i] ∗ (size [i] − 1) / 2
  • #include
    #include
    #include
    using namespace std;
    const int N=1e4+10,M=1e5+10;
    int n,m,tot,head[N],dfn[N],dcnt,c[N],scnt,size[N],vis[N],tot2,head2[N],ans;
    struct Edge{
    	int to,next;
    }e[M],e2[M];
    void add(int u,int v){
    	e[++tot].to=v;
    	e[tot].next=head[u];
    	head[u]=tot;
    } 
    void add2(int u,int v){
    	e2[++tot2].to=v;
    	e2[tot2].next=head2[u];
    	head2[u]=tot2;
    }
    void dfs1(int x){
    	vis[x]=1;
    	for(int i=head[x];i;i=e[i].next){
    		int y=e[i].to;
    		if(!vis[y]) dfs1(y);
    	}
    	dfn[++dcnt]=x;
    }
    void dfs2(int x){
    	c[x]=scnt;size[scnt]++;
    	for(int i=head2[x];i;i=e2[i].next){
    		int y=e2[i].to;
    		if(!c[y]) dfs2(y);
    	}
    }
    int main(){
    	cin>>n>>m;
    	for(int u,v,i=1;i<=m;i++){
    		cin>>u>>v;
    		add(u,v);add2(v,u);		
    	}
    	for(int i=1;i<=n;i++){
    		if(!vis[i]) dfs1(i);
    	}
    	for(int i=n;i>=1;i--){
    		if(!c[dfn[i]]) ++scnt,dfs2(dfn[i]);
    	}
    	for(int i=1;i<=n;i++){
    		int x=size[i];
    		ans+=x*(x-1)/2;
    	}
    	cout<<ans<<endl;
    }
    

    좋은 웹페이지 즐겨찾기