题意:给定一个图,给定一个人的行走路线,已知走的是最短路,问可能的目的地有哪些?
做法:先求起点到每一点的最短距离,然后求终点到每一点的最短距离(这次不允许经过路径上的点)。
如果 从起点到某点的距离 == 终点到某点的距离 + 路径长度 - 1 ,那么,这个点就有可能是目的地。
#define FOR(i,n) for(long long (i)=1;(i)<=(n);(i)++)
#define For(i,n) for(long long (i)=0;(i)<(n);(i)++)
using namespace std;
struct ArcNode{
int to;
ArcNode*next;
};
struct Node{
int D[2];
bool vis;
ArcNode *List;
}node[32768];
void Arc(int from,int to){
ArcNode *temp=new ArcNode;
temp->to=to;
temp->next=node[from].List;
node[from].List=temp;
}
void DArc(int from,int to){
Arc(from,to);Arc(to,from);
}
int N,M;
queue<int>Q;
void bfs(int k,int t){
ArcNode*temp=node[k].List;
while(temp){
if(t&&node[temp->to].vis) {
temp=temp->next;
continue;
}
if(!~node[temp->to].D[t]||node[temp->to].D[t]>node[k].D[t]+1){
node[temp->to].D[t]=node[k].D[t]+1;
Q.push(temp->to);
}
temp=temp->next;
}
}
void caculate(int v,int t){
while(!Q.empty()) Q.pop();
node[v].D[t]=0;
Q.push(v);
while(!Q.empty()){
int cnt=Q.front();Q.pop();
bfs(cnt,t);
}
}
int main(void)
{
while(cin>>N){
FOR(i,32767) node[i].D[0]=-1,node[i].D[1]=-1,node[i].List=NULL,node[i].vis=0;
For(i,N){
int n,last;scanf("%d%d",&n,&last);
For(j,n-1){
int a;scanf("%d",&a);
DArc(a,last);
last=a;
}
}
scanf("%d",&M);int A,B;//起点,终点
For(i,M){
if(i){
scanf("%d",&B);
node[B].vis=1;
}
else{
scanf("%d",&A);
node[A].vis=1;
}
}
if(M==1) B=A;
caculate(A,0);
caculate(B,1);
for(int i=1;i<=32767;i++){
if(i==B){
printf("%d\n",i);continue;
}
if(node[i].List&&!node[i].vis){
if(~node[i].D[0]&&~node[i].D[1]){
if(node[i].D[0]+1==node[i].D[1]+M){
printf("%d\n",i);
}
}
}
}
}
return 0;
}