zoukankan      html  css  js  c++  java
  • (tajan+floyd) zoj 3232

    It's not Floyd Algorithm

    Time Limit: 4 Seconds      Memory Limit: 32768 KB

    When a directed graph is given, we can solve its transitive closure easily using the well-known Floyd algorithm.

    But if you're given a transitive closure, can you give a corresponding directed graph with minimal edges?

    Input

    About 100 test cases, seperated by blank line.

    First line of each case is an integer N (1<=N<=200). The following N lines represent the given transitive closure in 0-1 matrix form, each line has N numbers.

    Output

    For each case, just output the number of minimal edges of a directed graph which has a given transitive closure.

    Sample Input

    1
    1
    
    2
    1 0
    0 1
    
    2
    1 1
    1 1
    
    3
    1 1 1
    0 1 1
    0 0 1
    

    Sample Output

    0
    0
    2
    2
    

    Hint

    Transitive closure can be presented as a matrix T, where Ti,j is true if and only if there is a path from vertex i to j.

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    #include<vector>
    #include<stack>
    using namespace std;
    stack<int> s;
    vector<int> e[205];
    int n,mp[205][205],Dfs[205],low[205],cmp[205][205],use[205],num[205],top,newflag;
    bool isstack[205];
    void init()
    {
        memset(num,0,sizeof(num));
        memset(isstack,0,sizeof(isstack));
        memset(mp,0,sizeof(mp));
        memset(cmp,0,sizeof(cmp));
        memset(low,0,sizeof(low));
        memset(use,0,sizeof(use));
        memset(Dfs,0,sizeof(Dfs));
        top=0,newflag=0;
        while(!s.empty())
            s.pop();
        for(int i=1;i<=n;i++)
            e[i].clear();
    }
    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(Dfs[u]==low[u])
        {
            newflag++;
            int x;
            do
            {
                x=s.top();
                use[x]=newflag;
                num[newflag]++;
                s.pop();
                isstack[x]=0;
            }while(x!=u);
        }
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            int ans=0;
            init();
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                    scanf("%d",&cmp[i][j]);
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(cmp[i][j]&&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++)
                {
                    if(use[i]!=use[e[i][j]]&&cmp[i][e[i][j]])
                    {
                        mp[use[i]][use[e[i][j]]]=1;
                    }
                }
            }
            for(int i=1;i<=newflag;i++)
            {
                if(num[i]!=1)
                    ans+=num[i];
            }
            for(int k=1;k<=newflag;k++)
            {
                for(int i=1;i<=newflag;i++)
                {
                    for(int j=1;j<=newflag;j++)
                    {
                        if(mp[i][k]&&mp[k][j]&&mp[i][j])
                          mp[i][j]=0;
                    }
                }
            }
            for(int i=1;i<=newflag;i++)
            {
                for(int j=1;j<=newflag;j++)
                {
                    if(mp[i][j])
                        ans++;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    第14章 位图和位块传输_14.1-14.3 位图基础
    第13章 使用打印机_13.2 打印图形和文字
    第13章 使用打印机_13.1 打印基础
    第12章 剪贴板_12.3 实现一个剪贴板查看器
    第12章 剪贴板_12.2 剪贴板的高级用法
    第12章 剪贴板_12.1 剪贴板的简单用法
    第11章 对话框_11.3 通用对话框
    第11章 对话框_11.2 非模态对话框
    第11章 对话框_11.1 模态对话框
    第5章 作业和进程池(2)
  • 原文地址:https://www.cnblogs.com/water-full/p/4511575.html
Copyright © 2011-2022 走看看