zoukankan      html  css  js  c++  java
  • (tarjan建图+topsort+状态压缩) bzoj 2208

    2208: [Jsoi2010]连通数

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 1489  Solved: 606
    [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

     
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<string>
    #include<algorithm>
    #include<bitset>
    #include<queue>
    #include<vector>
    #include<stack>
    using namespace std;
    vector<int> e[2005],g[2005];
    stack<int> s;
    bitset<2005> f[2005];
    int n,mp[2005][2005];
    int Dfs[2005],low[2005],use[2005],top,newflag,isstack[2005],in[2005],num[2005];
    bool vis[2005][2005];
    void tarjan(int u)
    {
        Dfs[u]=low[u]=++top;
        isstack[u]=1;
        s.push(u);
        for(int i=0;i<e[u].size();i++)
        {
            int v=e[u][i];
            if(!Dfs[v])
            {
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else if(isstack[v])
                low[u]=min(low[u],Dfs[v]);
        }
        if(low[u]==Dfs[u])
        {
            newflag++;
            int x;
            do
            {
                x=s.top();
                s.pop();
                isstack[x]=0;
                use[x]=newflag;
                num[newflag]++;
            }while(x!=u);
        }
    }
    void topsort()
    {
        queue<int> q;
        for(int i=1;i<=newflag;i++)
        {
            f[i][i]=1;
            if(in[i]==0)
                q.push(i);
        }
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            for(int i=0;i<g[x].size();i++)
            {
                int v=g[x][i];
                f[v]=f[v]|f[x];
                if(--in[v]==0)
                    q.push(v);
            }
        }
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                scanf("%1d",&mp[i][j]);
                if(i!=j&&mp[i][j])
                    e[i].push_back(j);
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(!Dfs[i])
                tarjan(i);
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<e[i].size();j++)
            {
                int u,v;
                u=i,v=e[i][j];
                if(use[u]!=use[v]&&!vis[use[u]][use[v]])
                {
                    g[use[u]].push_back(use[v]);
                    vis[use[u]][use[v]]=1;
                    in[use[v]]++;
                }
            }
        }
        topsort();
        int ans=0;
        for(int i=1;i<=newflag;i++)
        {
            for(int j=1;j<=newflag;j++)
            {
                if(f[i][j])
                    ans+=num[i]*num[j];
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    

      

  • 相关阅读:
    websocket+nodejs+redis实现消息订阅和发布系统
    nodejs下载图片到本地,根据百度图片查找相应的图片,通过nodejs保存到本地文件夹
    基于vue 2.X和高德地图的vue-amap组件获取经纬度
    获取Class对象的三种方式
    java中的回调机制的理解(小例子)
    URL和URI的区别
    java web开发中各类地址的写法
    ListView性能
    Android中的Handler, Looper, MessageQueue和Thread对应关系
    java几种常用的算法
  • 原文地址:https://www.cnblogs.com/water-full/p/4516235.html
Copyright © 2011-2022 走看看