[强连通分支]poj_1236_network of schools
2012-03-13 15:03
369 查看
题意:给定一个有向图,求最少要从几个结点开始能把图遍历完,最少添加多少条边,使得整个图强连通。
先缩点,然后对于缩点以后的图,入度为0的点的个数就是第一问的解,第二问的解是入度为0结点个数和出度为0结点个数中的最大值,第二问参考的解题报告是:http://hi.baidu.com/oichampion/blog/item/1882abd7d86adec5a9ec9aa5.html
代码:
先缩点,然后对于缩点以后的图,入度为0的点的个数就是第一问的解,第二问的解是入度为0结点个数和出度为0结点个数中的最大值,第二问参考的解题报告是:http://hi.baidu.com/oichampion/blog/item/1882abd7d86adec5a9ec9aa5.html
代码:
#include<iostream> #include<cstring> #include<cstdio> #include<vector> #include<stack> using namespace std; #define MIN(a,b) a>b?b:a #define MAX(a,b) a<b?b:a const int MAXN = 110; int sg[MAXN][MAXN],vis[MAXN],dfn[MAXN],low[MAXN],belong[MAXN],indeg[MAXN],outdeg[MAXN],scnt,deep; vector<int> g[MAXN]; stack<int> S; void init() { memset(belong,-1,sizeof(belong)); memset(vis,0,sizeof(vis)); memset(sg,0,sizeof(sg)); memset(indeg,0,sizeof(indeg)); memset(outdeg,0,sizeof(outdeg)); for(int i=0;i<MAXN;i++)g[i].clear(); while(!S.empty())S.pop();scnt=0;deep=0; } void tarjan(int u,int &deep) { low[u] = dfn[u] = deep; vis[u] = 1;S.push(u);deep++; for(int i=0;i<g[u].size();i++) { int v = g[u][i]; if(!vis[v]) { tarjan(v,deep); low[u] = MIN(low[u],low[v]); } else if(belong[v]==-1) { low[u] = MIN(low[u],dfn[v]); } } if(low[u]==dfn[u]) { int v; do { v = S.top(); S.pop(); belong[v] = scnt; }while(v!=u); scnt++; } } void getscc(int n) { for(int i=1;i<=n;i++) { if(!vis[i])tarjan(i,deep); } } void getsg(int n)//获得缩点图 { for(int i=1;i<=n;i++) { for(int j=0;j<g[i].size();j++) { if(belong[i]!=belong[g[i][j]]) { sg[belong[i]][belong[g[i][j]]]=1; } } } } void cacsgindeg()//计算缩点图的入度 { for(int i=0;i<scnt;i++) { for(int j=0;j<scnt;j++) { if(sg[j][i])indeg[i]++; if(sg[i][j])outdeg[i]++; } } } int getzerodeg() { int cnt = 0; for(int i=0;i<scnt;i++) { if(indeg[i]==0)cnt++; } return cnt; } int getzeroout() { int cnt = 0; for(int i=0;i<scnt;i++) { if(outdeg[i]==0)cnt++; } return cnt; } int main() { int n; while(scanf("%d",&n)!=EOF) { int u;init(); for(int i=1;i<=n;i++) { while(scanf("%d",&u),u) { g[i].push_back(u); } } getscc(n); getsg(n); cacsgindeg(); int copy = getzerodeg(),edge = MAX(copy,getzeroout()); if(scnt!=1){ printf("%d\n%d\n",copy,edge); }else printf("1\n0\n"); } return 0; }
相关文章推荐
- poj 1236 Network of Schools (强连通分支缩点)
- poj 1236 Network of Schools【强连通求孤立强连通分支个数&&最少加多少条边使其成为强连通图】
- POJ 1236 Network of Schools 强连通分支 .
- 【连通图|强连通分量+缩点】POJ-1236 Network of Schools
- poj 1236 Network of Schools
- POJ 1236 Network Of Schools ( tarjan求强连通分量 + 缩点成DAG图 )
- POJ 1236 Network of Schools
- POJ 1236 Network of Schools (强连通 出度 入度)
- POJ 1236 Network of Schools 已翻译
- POJ 1236 Network of Schools (tarjan求强连通,缩点)
- POJ 1236 Network of Schools【强连通缩点】【Tarjan算法】
- [ACM] poj 1236 Network of Schools (有向强连通分量)
- poj 1236——Network of Schools
- POJ 1236 Network of Schools【强连通缩点】
- |poj 1236|强连通分量|Network of Schools
- POJ 1236 Network of Schools
- POJ1236 Network of Schools
- poj 1236 Network of Schools
- POJ 1236 Network of Schools
- POJ 1236 Network of Schools(强连通 Tarjan+缩点)