%%%BYVOID
注意到题上的一个看似无关紧要的条件,“不包括三角形”,这是一个突破口。由这个条件,我们可以证明,如果一个图不存在度数为1的顶点,B永远也追不上A。也就是B想追上A,必须让A“走投无路”。
于是我们首先把原图处理一下,求出对于A来说的安全区。对于A来说的安全区,也就是一个没有度为1的顶点的最大子图。我们把这个安全区求出,并标记上。
A要想不被B抓住,则一定要向安全区中逃跑。如果A能够在B追上A之前逃离到安全区,则B就永远也追不上A。否则,A无论如何也会被B追上。在A“必死无疑”的时候,A要想尽可能晚的被B追上,就必须想远离B的方向跑。
有了以上的分析,得出下列算法 1、求出安全区的顶点。 2、分别求出A,B初始位置开始,到每个顶点的距离,记作DA[i]和DB[i]。 3、若存在安全区中的顶点k,使得DA[k]<DB[k],则B追不上A,输出"NIE",结束。 4、如果不存在上述顶点k,则找到满足DA[i]<DB[i]时,DB[i]的最大值,输出DB[i]的最大值。
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
typedef pair<int,int> abcd;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int N=3005;
const int M=15005;
struct edge{
int u,v,next;
}G[M<<1];
int head[N],inum=1;
inline void add(int u,int v,int p){
G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;
}
int n,m,A,B;
abcd edges[M];
int Q[N],l,r;
int DA[N],DB[N];
int dan[N];
#define V G[p].v
inline void Dist(){
memset(DA,-1,sizeof(DA));
l=r=-1;
Q[++r]=A; DA[A]=0;
while (l<r){
int u=Q[++l];
for (int p=head[u];p;p=G[p].next)
if (DA[V]==-1)
DA[V]=DA[u]+1,Q[++r]=V;
}
memset(DB,-1,sizeof(DB));
l=r=-1;
Q[++r]=B; DB[B]=0;
while (l<r){
int u=Q[++l];
for (int p=head[u];p;p=G[p].next)
if (DB[V]==-1)
DB[V]=DB[u]+1,Q[++r]=V;
}
}
int deg[N];
inline void Safe(){
l=r=-1;
for (int i=1;i<=n;i++) if (deg[i]==1) Q[++r]=i;
while (l<r){
int u=Q[++l];
dan[u]=1;
for (int p=head[u];p;p=G[p].next){
deg[V]--;
if (deg[V]==1) Q[++r]=V;
}
}
}
int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n); read(m); read(A); read(B);
for (int i=1;i<=m;i++) read(edges[i].first),read(edges[i].second);
sort(edges+1,edges+m+1);
m=unique(edges+1,edges+m+1)-edges-1;
for (int i=1;i<=m;i++){
add(edges[i].first,edges[i].second,++inum),add(edges[i].second,edges[i].first,++inum);
deg[edges[i].first]++; deg[edges[i].second]++;
}
Dist();
Safe();
int Ans=0;
for (int i=1;i<=n;i++){
if (!dan[i] && DA[i]<DB[i])
return printf("NIE\n"),0;
if (DA[i]<DB[i])
Ans=max(Ans,DB[i]);
}
printf("%d\n",Ans);
return 0;
}