求有向图割点和分裂点,由于数据很小,直接枚举,去掉某点,然后判断即可,需要注意的地方是分裂点一定是割点
- #include <iostream>
- #include <algorithm>
- #include <map>
- #include <vector>
- using namespace std;
- /*
- PROG: race3
- LANG: C++
- ID: heben991
- */
- const int N = 110;
- int n, m, low[N],num[N], g[N][N];
- bool cut[N], split[N];
- int mark[N];
- void dfs_cut(int x)
- {
- int i, j, k, t;
- mark[x]=1;
- for(i = 0; i <= n; ++i)
- if(g[x][i] && !mark[i])
- {
- dfs_cut(i);
- }
- }
- void dfs1(int x)
- {
- int i;
- mark[x]=1;
- for(i = 0; i <= n; ++i)
- if(!mark[i] && g[x][i])
- {
- dfs1(i);
- }
- }
- bool dfs2(int x)
- {
- int i;
- bool ret=1;
- mark[x]=2;
- for(i = 0; i <= n; ++i)
- if(g[x][i] && mark[i]!=2)
- {
- if(mark[i]==1)return 0;
- ret = ret && dfs2(i);
- }
- return ret;
- }
- bool get_split(int x)
- {
- int i, j, k, t;
- memset(mark,0,sizeof(mark));
- mark[x]=1; // key step
- dfs1(0);
- mark[x]=0;
- return dfs2(x);
- }
- int main()
- {
- int i, j, k, t, x, y;
- freopen("race3.in", "r", stdin);
- freopen("race3.out","w",stdout);
- while( scanf("%d", &x)==1 && x!=-1)
- {
- while(x!=-2)
- {
- if(x!=n)g[n][x] = 1;
- scanf("%d", &x);
- }
- ++n;
- }
- --n;
- int count=0;
- for(i = 1; i < n; ++i)
- {
- memset(mark,0,sizeof(mark));
- mark[i] = 1;
- dfs_cut(0);
- if(!mark[n]) cut[i] = 1, ++count;
- }
- printf("%d",count);
- count = 0;
- for(i = 1; i < n; ++i)
- if(cut[i])
- {
- printf(" %d", i);
- split[i] = get_split(i);
- if(split[i]) count++;
- }
- puts("");
- printf("%d", count);
- for(i = 1; i < n; ++i)
- if(split[i])printf(" %d",i);
- puts("");
- return 0;
- }