bzoj3541: Spoj59 Bytelandian Information Agency

Description

       BIA机构内部使用一个包含N台计算机的网络。每台计算机被标号为1..N,并且1号机是服务器。计算机被一些单向传输线连接着,每条数据线连接两台计算机。服务器可以向任何一台计算机直接或者间接的发送数据包。
       当BIA得到新的信息,数据被放在服务器上,然后通过网络分发到各台计算机。BIA的首脑在考虑如果一台计算机停止工作(例如被黑客攻击)将会发生什么,有可能一些计算机将因此得不到服务器上的数据。我们称这种计算机是critical的。
       如下图,有两台critical计算机1、2。1是服务器,而所有1到3的数据都必须经过2。
 

Input

N , M (N为点数,M为边数) N≤5000 , N-1≤M≤200000
 接下来M行每行两个数表示每条连接线的出发计算机和接收计算机的编号。

Output

第一行有一个整数K表示critical计算机的数目
第二行包含K个整数描述了所有critical计算机的编号。

Sample Input

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

Sample Output

2
1 2
 
题解:
这是Dominator Tree裸题,具体见李煜东在2013WC上的课件《图连通性 若干拓展问题探讨》
code:
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<vector>
 5 #include<cstring>
 6 #include<algorithm>
 7 #define maxn 5005
 8 #define maxm 200005
 9 #define inf maxn
10 using namespace std;
11 char ch;
12 bool ok;
13 void read(int &x){
14     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
15     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
16     if (ok) x=-x;
17 }
18 int n,m,a,b;
19 int idx,dfn[maxn],id[maxn],fa[maxn];
20 int pa[maxn],best[maxn],semi[maxn],idom[maxn];
21 vector<int> dom[maxn];
22 struct Graph{
23     int tot,now[maxn],son[maxm],pre[maxm];
24     void put(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b;}
25     void dfs(int u){
26         dfn[u]=++idx,id[idx]=u;
27         for (int p=now[u],v=son[p];p;p=pre[p],v=son[p]) if (!dfn[v]) fa[v]=u,dfs(v);
28     }
29 }G1,G2;
30 int find(int u){
31     if (u==pa[u]) return u;
32     int fa=find(pa[u]);
33     if (semi[best[u]]>semi[best[pa[u]]]) best[u]=best[pa[u]];
34     pa[u]=fa;
35     return fa;
36 }
37 void get(){
38     G1.dfs(1);
39     for (int i=1;i<=n;i++) pa[i]=i;
40     for (int i=1;i<=n;i++) best[i]=i;
41     for (int i=1;i<=n;i++) semi[i]=inf;
42     for (int i=n;i>=2;i--){
43         int u=id[i],j=dfn[fa[u]];
44         for (int p=G2.now[u],v=G2.son[p];p;p=G2.pre[p],v=G2.son[p]){
45             if (dfn[v]>i) find(dfn[v]),semi[i]=min(semi[i],semi[best[dfn[v]]]);
46             else semi[i]=min(semi[i],dfn[v]);
47         }
48         dom[semi[i]].push_back(i),pa[i]=j;
49         for (unsigned int k=0;k<dom[j].size();k++){
50             int v=dom[j][k];
51             find(v);
52             if (semi[best[v]]<j) idom[v]=best[v]; else idom[v]=j;
53         }
54         dom[j].clear();
55     }
56     for (int i=2;i<=n;i++){
57         if (idom[i]!=semi[i]) idom[i]=idom[idom[i]];
58         dom[id[idom[i]]].push_back(id[i]);
59     }
60     idom[1]=0;
61 }
62 int main(){
63     read(n),read(m);
64     for (int i=1;i<=m;i++) read(a),read(b),G1.put(a,b),G2.put(b,a);
65     get();
66     int ans=0;
67     for (int i=1;i<=n;i++) if (dom[i].size()) ans++;
68     printf("%d
",ans);
69     bool flag=0;
70     for (int i=1;i<=n;i++) if (dom[i].size()){
71         if (flag) putchar(' '); else flag=1;
72         printf("%d",i);
73     }
74     puts("");
75     return 0;
76 }
原文地址:https://www.cnblogs.com/chenyushuo/p/5111014.html