原题链接:https://vjudge.net/problem/UVA-12569
分类:状态压缩
备注:BFS,技巧判重
结点数不大于15,很容易想到状态压缩,判重数组为vis[机器人位置][整体状态]的形式,然后输出带点技巧就ok了。
#include<bits/stdc++.h>
using namespace std;
const int maxn=20;
int T,n,m,s,t;
struct node{
int state,robot,pre,stp,id;
}p[1<<maxn];
bool vis[maxn][1<<maxn];
vector<int>e[maxn];
void print(int ind){
if(p[ind].pre==-1)return;
print(p[ind].pre);
int from=p[p[ind].pre].state^(p[p[ind].pre].state&p[ind].state);
int to=p[ind].state^(p[p[ind].pre].state&p[ind].state);
int u,v;
for(int i=1;i<=n;i++){
if(1<<i&from)u=i;
if(1<<i&to)v=i;
}
printf("%d %d\n",u,v);
}
int main(void){
//freopen("in.txt","r",stdin);
scanf("%d",&T);
for(int cas=1;cas<=T;cas++){
memset(vis,0,sizeof(vis));
scanf("%d %d %d %d",&n,&m,&s,&t);
int sta=0,cnt=0,ans=-1;
for(int i=1;i<=n;i++)e[i].clear();
for(int i=0;i<m;i++){
int x; scanf("%d",&x);
sta|=(1<<x);
}
sta|=(1<<s);
for(int i=1;i<=n-1;i++){
int u,v;scanf("%d %d",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
queue<node>q;
p[0].id=0; p[0].state=sta; p[0].pre=-1;
p[0].robot=s; p[0].stp=0;
vis[p[0].robot][p[0].state]=true;
q.push(p[0]);
while(!q.empty()){
node u=q.front(); q.pop();
if(u.robot==t){ans=u.id; break;}
for(int i=1;i<=n;i++){
if((1<<i)&u.state){
for(int j=0;j<e[i].size();j++){
if(u.state&(1<<e[i][j]))continue;
node v=u; v.state^=(1<<i);
v.stp++; v.pre=u.id;
v.state|=(1<<e[i][j]);
if(i==u.robot)v.robot=e[i][j];
if(vis[v.robot][v.state])continue;
vis[v.robot][v.state]=true;
v.id=++cnt;
p[cnt]=v; q.push(v);
}
}
}
}
printf("Case %d: ",cas);
if(ans==-1)printf("-1\n");
else {printf("%d\n",p[ans].stp); print(ans);}
printf("\n");
}
return 0;
}