zoukankan      html  css  js  c++  java
  • Codeforces Round #286 (Div. 1) B. Mr. Kitayuta's Technology (强连通分量)

    题目地址:http://codeforces.com/contest/506/problem/B
    先用强连通判环。然后转化成无向图,找无向图连通块。若一个有n个点的块内有强连通环,那么须要n条边。即正好首尾相连形成一条环,那么有了这个环之后,在这个块内的全部要求都能实现。

    假设没有强连通环,那么就是一棵树,那么仅仅须要n-1条边就可以。


    代码例如以下:

    #include <iostream>
    #include <string.h>
    #include <math.h>
    #include <queue>
    #include <algorithm>
    #include <stdlib.h>
    #include <map>
    #include <set>
    #include <stdio.h>
    #include <time.h>
    using namespace std;
    #define LL long long
    #define pi acos(-1.0)
    #pragma comment(linker, "/STACK:1024000000")
    const int mod=1e9+7;
    const int INF=0x3f3f3f3f;
    const double eqs=1e-9;
    const int MAXN=100000+10;
    int head[MAXN], cnt;
    int dfn[MAXN], low[MAXN], scc, belong[MAXN], instk[MAXN], stk[MAXN], indx, tot[MAXN], top;
    int vis[MAXN];
    int flag, num;
    struct node
    {
            int u, v, next;
    }edge[MAXN<<1];
    void add(int u, int v)
    {
            edge[cnt].u=u;
            edge[cnt].v=v;
            edge[cnt].next=head[u];
            head[u]=cnt++;
    }
    void init()
    {
            memset(head,-1,sizeof(head));
            cnt=indx=top=0;
            memset(dfn,0,sizeof(dfn));
            memset(instk,0,sizeof(instk));
            memset(tot,0,sizeof(tot));
    }
    void tarjan(int u)
    {
            dfn[u]=low[u]=++indx;
            stk[++top]=u;
            instk[u]=1;
            for(int i=head[u];i!=-1;i=edge[i].next){
                    int v=edge[i].v;
                    if(!dfn[v]){
                            tarjan(v);
                            low[u]=min(low[u],low[v]);
                    }
                    else if(instk[v]) low[u]=min(low[u],dfn[v]);
            }
            if(dfn[u]==low[u]){
                    scc++;
                    while(1){
                            int v=stk[top--];
                            belong[v]=scc;
                            instk[v]=0;
                            tot[scc]++;
                            if(u==v) break;
                    }
            }
    }
    void dfs(int u)
    {
            num++;
            vis[u]=1;
            if(tot[belong[u]]>=2) flag=1;
            for(int i=head[u];i!=-1;i=edge[i].next){
                    int v=edge[i].v;
                    if(vis[v]) continue ;
                    dfs(v);
            }
    }
    int main()
    {
            int n, m, u, v, i, j, ans;
            while(scanf("%d%d",&n,&m)!=EOF){
                    init();
                    while(m--){
                            scanf("%d%d",&u,&v);
                            add(u,v);
                    }
                    ans=0;
                    for(i=1;i<=n;i++){
                            if(!dfn[i])
                                    tarjan(i);
                    }
                    m=cnt;
                    for(i=0;i<m;i++){
                            u=edge[i].u;
                            v=edge[i].v;
                            add(v,u);
                    }
                    memset(vis,0,sizeof(vis));
                    ans=0;
                    for(i=1;i<=n;i++){
                            if(!vis[i]){
                                    num=flag=0;
                                    dfs(i);
                                    ans+=num-1+flag;
                            }
                    }
                    printf("%d
    ",ans);
            }
            return 0;
    }
    
  • 相关阅读:
    熟悉常用的HDFS操作
    爬虫爬取小说网站
    数据结构化与保存
    使用正则表达式,取得点击次数,函数抽离
    爬取校园新闻首页的新闻
    网络爬虫基础练习
    综合练习:词频统计
    最近在学习多元分析,有空放上来分享
    机器学习基石作业一15-20题(Python实现)
    2018十月份
  • 原文地址:https://www.cnblogs.com/jhcelue/p/7068788.html
Copyright © 2011-2022 走看看