poj 1236 tarjan缩点(能达到全图的最少起点数)

来源:互联网 发布:mycat 性能优化 编辑:程序博客网 时间:2024/05/17 07:37

题意:有若干学校,某些学校可以达到其他学校。问题1:一个新软件要给予全部学校最少给多少个学校;问题2:将软件随机给学校,问较之问题1的最少数量需要增加多少条道路?

思路:tarjan求强连通分量,之后缩点形成有向无环图。有向无环图中所有入度不为0的点,一定可以由某个入度为0的点出发可达。 (由于无环,所以从任何入度不为0的点往回走,必然终止于一个入度为0的点)。问题一为此图入度为0的定点数。问题2为图中入度为0和出度为0的顶点数量的大者。

输入:

5
2 4 3 0
4 5 0
0
0
1 0

输出:

1

2

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>#include <cstdlib>using namespace std;#define INF 0x3fffffff#define N 105struct edge{    int y,next;}e[N*N*2];int n,first[N],top,dfn[N],low[N];int in[N],out[N],strong[N],stack[N],instack[N],con,id,ts;void add(int x,int y){    e[top].y = y;    e[top].next = first[x];    first[x] = top++;}void tarjan(int x){    int i;    dfn[x] = low[x] = ++id;    stack[ts++] = x;    instack[x] = 1;    for(i = first[x];i!=-1;i=e[i].next){        if(dfn[e[i].y] == -1){            tarjan(e[i].y);            low[x] = min(low[x],low[e[i].y]);        }else if(instack[e[i].y])            low[x] = min(low[x],dfn[e[i].y]);    }    if(dfn[x] == low[x]){        con++;        do{            strong[stack[--ts]] = con;            instack[stack[ts]] = 0;        }while(x!=stack[ts]);    }}int main(){    int i,j,res1,res2;    scanf("%d",&n);    top = id = con = ts = res1 = res2 = 0;    memset(first, -1, sizeof(first));    memset(dfn, -1, sizeof(dfn));    memset(low, 0, sizeof(low));    memset(instack, 0, sizeof(instack));    memset(in, 0, sizeof(in));    memset(out, 0, sizeof(out));    for(i = 1;i<=n;i++)        while(scanf("%d",&j) && j)            add(i,j);    for(i = 1;i<=n;i++)        if(dfn[i] == -1)            tarjan(i);    if(con == 1){//只有一个强连通分量时候要特判!!!!!!        printf("1\n0\n");        return 0;    }    for(i = 1;i<=n;i++)        for(j = first[i];j!=-1;j=e[j].next)            if(strong[i] != strong[e[j].y]){                out[strong[i]]++;                in[strong[e[j].y]]++;            }    for(i = 1;i<=con;i++){        if(!in[i])            res1++;        if(!out[i])            res2++;    }    printf("%d\n%d\n",res1,max(res1,res2));    return 0;}


0 0
原创粉丝点击