zoukankan      html  css  js  c++  java
  • BZOJ 2208 Jsoi2010 连通数

    2208: [Jsoi2010]连通数

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 3328  Solved: 1457
    [Submit][Status][Discuss]

    Description

    Input

    输入数据第一行是图顶点的数量,一个正整数N。 接下来N行,每行N个字符。第i行第j列的1表示顶点i到j有边,0则表示无边。

    Output

    输出一行一个整数,表示该图的连通数。

    Sample Input

    3
    010
    001
    100

    Sample Output

    9

    HINT

    对于100%的数据,N不超过2000。

    Source

    第一轮

    暴力n^2是可以过得

    正解是tarjin缩完点,递推一下

    #include <bits/stdc++.h>
    #define ll long long
    #define eps 1e-7
    using namespace std;
    inline int read(){
        int x=0;int f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const int MAXN=5e6+10;
    struct node{
        int y,next;
    }e[MAXN];
    int linkk[MAXN],len=0,a[2010][2010],low[MAXN],dfs_clock=0,dfn[MAXN],cnt[MAXN],sum[MAXN],f[MAXN],tot=0,vis[2100],n,m,ine[MAXN],stark[MAXN],top=0;
    inline void insert(int xx,int yy){
        e[++len].y=yy;e[len].next=linkk[xx];linkk[xx]=len;
    }
    namespace zhangenming{
        void tarjin(int st){
            dfn[st]=low[st]=++dfs_clock;
            vis[st]=1;stark[++top]=st;
            for(int i=linkk[st];i;i=e[i].next){
                if(!dfn[e[i].y]){
                    tarjin(e[i].y);
                    low[st]=min(low[st],low[e[i].y]);
                }
                else if(vis[e[i].y]) low[st]=min(low[st],dfn[e[i].y]);
            }
            if(low[st]==dfn[st]){
                ++tot;
                int k;
                do{
                    k=stark[top--];
                    ine[k]=tot;
                    vis[k]=0;
                    sum[tot]++;
                }while(k!=st);
            }
        }
        void rebuild(){
            len=0;memset(linkk,0,sizeof(linkk));
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    if(ine[i]!=ine[j]&&a[i][j]){
                        insert(ine[i],ine[j]);
                        cnt[ine[j]]++;
                    }
                }
            }
        }
        void init(){
            n=read();
            for(int i=1;i<=n;i++){
                char ch[2100];
                scanf("%s",ch+1);
                for(int j=1;j<=n;j++){
                    a[i][j]=ch[j]-'0';
                    if(a[i][j]) insert(i,j);
                }
            }
        }
        inline void dp(int st,int tn){
            vis[st]=1;
            for(int i=linkk[st];i;i=e[i].next){
                if(!vis[e[i].y]) dp(e[i].y,tn);
            }
            f[tn]+=sum[st];
        }
        void solve(){
            for(int i=1;i<=n;i++){
                if(!dfn[i]) tarjin(i);
            }
            rebuild();
            //cout<<tot<<endl;
            for(int i=1;i<=tot;i++){
                memset(vis,0,sizeof(vis));
                dp(i,i);
            }
            ll ans=0;
            for(int i=1;i<=tot;i++){
                ans+=(sum[i]*f[i]);
            }
            cout<<ans<<endl;
        }
    }
    int main(){
        //freopen("All.in","r",stdin);
        //freopen("zh.out","w",stdout);
        using namespace zhangenming;
        init();
        solve();
        return 0;
    }
    

      

  • 相关阅读:
    仿windows选项卡效果拾零(收藏)
    把一个字符串分开存入一个临时表中
    DOM的基本方法
    如何判断iframe加载完毕(原创)
    javascript中showModalDialog和showModelessDialog的使用(转)
    一个sql子查询作为过滤条件的例子(原创)
    关闭窗口,弹出对话框
    设置C#程序在Windows 7 Vista下以管理员权限运行(转)
    SQL SERVER 6 视图与索引
    SQL SERVER 各类触发器的完整语法及参数说明(拓展)
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/8041143.html
Copyright © 2011-2022 走看看