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
1 2
1 4
2 3
3 4
4 2
Sample Output
2
1 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\n",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 }