ZJOI2004——嗅探器
描述
某军搞信息对抗实战演习.红军成功地侵入了蓝军的内部网络.蓝军共有两个信息中心.红军计划在某台中间服务器上安装一个嗅探器,从而能够侦听到两个信息中心互相交换的所有信息.但是蓝军的网络相当的庞大,数据包从一个信息中心传到另一个信息中心可以不止有一条通路.现在需要你尽快地解决这个问题.应该把嗅探器安装在哪个中间服务器上才能保证所有的数据包都能被捕获?
输入
第一行一个整数n(1<=n<=100),表示蓝军网络中服务器的数目.
接下来若干行是对蓝军网络的拓扑结构描述.每行是两个整数i,j表示编号为I和编号为j的两台服务器间存在连接(显然连接是双向的).
服务器的编号从1开始.描述一两个0结束.再接下来一行是两个整数a,b分别表示两个中心服务器的编号
.如果有多个解输出编号最小的一个.
如果找不到任何解,输出”No solution”.
输出
样例输入
5
2 1
2 5
1 4
5 3
2 3
5 1
0 0
4 2样例输出
1
一道显然的求割点
从s到tDfs之后往回回溯时统计答案就是了
#include<bits/stdc++.h>
using namespace std;
inline int read(){
char ch=getchar();
int res=0;
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return res;
}
int low[105],adj[105],nxt[20005],to[20005],dfn[20005],n,s,t,ans=1000000000,fa[105],tot,cnt;
inline void addedge(int u,int v){
nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v;
nxt[++cnt]=adj[v],adj[v]=cnt,to[cnt]=u;
}
inline void tarjan(int u,int f){
dfn[u]=low[u]=++tot;
for(int e=adj[u];e;e=nxt[e]){
int v=to[e];
if(!dfn[v]){
fa[v]=u;
tarjan(v,u);
low[u]=min(low[u],low[v]);
}
if(v!=f){
low[u]=min(low[u],dfn[v]);
}
}
}
inline void find(int u){
if(u==s)return;
if(low[u]>=dfn[fa[u]]&&fa[u]!=s){
ans=min(ans,fa[u]);
}
find(fa[u]);
}
int main(){
n=read();
int u=read(),v=read();
while(u&&v){
addedge(u,v);
u=read(),v=read();
}
s=read(),t=read();
tarjan(s,0);
find(t);
if(ans==1000000000){
cout<<"No solution"<<'\n';
}
else cout<<ans<<'\n';
return 0;
}