poj1236 Network of Schools (Targan强连通图缩点)

来源:互联网 发布:手机淘宝怎样申请账号 编辑:程序博客网 时间:2024/06/05 09:04

第一道连通图题吧以此纪念下
题意:给一张有向无环图有两个任务

1.最至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点
2.至少要加多少条边,才能使得从任何一个顶点出发,都能到达全部顶点

解题思路:
1. 求出所有强连通分量
2. 每个强连通分量缩成一点,则形成一个有向无环图DAG。
3. DAG上面有多少个入度为0的顶点,问题1的答案就是多少
4. 在DAG上要加几条边,才能使得DAG变成强连通的,问题2的答案就是多少
5. 怎么加边呢:两种 n :表示入度为0的个数,m:出度为0的个数 问题2的答案 为 max(n,m);

1.求强连通分量采用的是Targan算法
不懂的移步吧 https://www.byvoid.com/zhs/blog/scc-tarjan

/*=================================================== * Author :     Uniontake * Email  :     mr.uniontake@gmail.com * File   :     A-poj1236-Network-of-Schools.cpp CPP * Creat Date : 2017-10-06 11:09:16 * Do one thing at a time, and do well===================================================*/#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <ctime>#include <iostream>#include <algorithm>#include <string>#include <vector>#include <deque>#include <list>#include <set>#include <map>#include <stack>#include <queue>#include <iomanip>#define mem(a,x) memset(a,x,sizeof(a))#define gcd(a,b) __gcd(a,b)#define lowbit(x) (x&-x)#define LL long long#define MOD 1000000007#define INF 0x3f3f3f3f#define pi (acos(-1.0))#define eps (1e-8)using namespace std;const int maxn = 110;int n;           //numint dfs_num;int dfn[maxn];   //递归次序int low[maxn];   //回溯堆栈中最早的节点int sta[maxn];bool vis[maxn];  //判断元素是否在堆栈中int maze[maxn][maxn]; //邻接矩阵int indegree[maxn],outdegree[maxn]; //出度入度int color[maxn];int colorsnum;int top;void Targan(int u){    dfn[u] = low[u] = ++dfs_num;    sta[top++] = u;    vis[u] = true;    for(int i=1;i<=n;i++) if(maze[u][i])    {        if(!dfn[i])        {            Targan(i);            low[u] = min(low[u],low[i]);        }        else if(vis[i]) { low[u] = min(low[u],dfn[i]); }    }    if(dfn[u] == low[u])    {        colorsnum++;        while(1)        {            int v = sta[--top];            color[v] = colorsnum;            vis[v] = false;            if( v == u ) break;        }    }   }void init(){    top = 0;    colorsnum = 0;    dfs_num = 0;    mem(color,0);    mem(maze,0);    mem(dfn,0);    mem(sta,0);    mem(low,0);    mem(vis,false);    mem(indegree,0);    mem(outdegree,0);}int main(){    while(~scanf("%d",&n))    {        init();        int x;        for(int i=1;i<=n;i++)        {            while(scanf("%d",&x))            {                if(!x) break;                maze[i][x] = 1;            }        }        for(int i=1;i<=n;i++) if(!dfn[i]) //图不是连通的            Targan(i);        if(colorsnum == 1)  //特判        {            printf("1\n0\n");            continue;        }        for(int i=1;i<=n;i++)        {            for(int j=1;j<=n;j++) if(maze[i][j] && color[i]!=color[j])            {                   outdegree[color[i]]++;                   indegree[color[j]]++;            }        }        int ans1,ans2;        ans1 = ans2 = 0;        for(int i=1;i<=colorsnum;i++)        {            if(!indegree[i]) ans1++;            if(!outdegree[i]) ans2++;        }        printf("%d\n%d\n",ans1,max(ans1,ans2));    }    return 0;}
阅读全文
0 0