标签:
Description
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 2Hint
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<cmath> #include<algorithm> #include<cstdlib> #include<queue> #include<vector> #include<stack> using namespace std; stack<int> s; vector<int> e[205]; int n,mp[205][205],Dfs[205],low[205],use[205],isstack[205],num[205]; int top,newflag; void init() { memset(mp,0,sizeof(mp)); memset(Dfs,0,sizeof(Dfs)); memset(low,0,sizeof(low)); memset(use,0,sizeof(use)); memset(isstack,0,sizeof(isstack)); memset(num,0,sizeof(num)); for(int i=1;i<=n;i++) e[i].clear(); top=0; newflag=0; while(!s.empty()) s.pop(); } void tarjan(int u) { Dfs[u]=low[u]=++top; s.push(u); isstack[u]=1; for(int i=0;i<e[u].size();i++) { int v=e[u][i]; if(!Dfs[v]) { tarjan(v); low[u]=min(low[v],low[u]); } 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(); use[x]=newflag; num[newflag]++; isstack[x]=0; }while(x!=u); } } int main() { int x; while(scanf("%d",&n)!=EOF) { init(); int ans=0; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { scanf("%d",&x); if(i!=j&&x) e[i].push_back(j); } } for(int i=1;i<=n;i++) { if(!Dfs[i]) tarjan(i); } for(int i=1;i<=newflag;i++) { if(num[i]!=1) ans+=num[i]; } for(int i=1;i<=n;i++) { for(int j=0;j<e[i].size();j++) { if(use[i]!=use[e[i][j]]) { mp[use[i]][use[e[i][j]]]=1; } } } 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\n",ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/a972290869/p/4432421.html