FJNU.1965
Description
小明是一个对计算机有着浓厚兴趣的初中生,暑假期间参加了学校组织的信息学夏令营。在老师的指导下,小明学到了很多计算机知识,不知不觉,渡过了一个令人难忘的夏令营。在夏令营结束的那天,老师让大家一起做一个换卡片的游戏,给每人发一张双面都写有一个数字的卡片,并且为每人指定一个幸运数字,这个数字一定会出现在某张卡片上。并要求大家通过与其他同学交换卡片,来获得一张包含自己幸运数字的卡片。交换的规则是,两张卡片至少有一个数字是相同的时候才能进行交换。老师让每位同学以最少的交换次数拿到包含自己幸运数字的卡片。请你帮小明算算,他最少要交换多少次才能获得那张包含他的幸运数字的卡片。
Input
输入的第一行含一个正整数k,表示测试例个数。下面紧接着k个测试例的数据。每个测试例数据的第一行含一个正整数N(N<=50000),表示卡片的数量;随后的一行包含一个正整数,表示老师指定给小明的幸运数字;紧接下来的N行每行由2个整数组成(整数取值的范围为1~50000),分别表示每张卡片两面上的数字。其中第一行的两个整数,即为发给小明的卡片上的两个整数。同一行的数据之间用一个空格隔开,两个测试例之间用一个空行隔开。
Output
对应每个测试例输出一个整数,表示卡片的最少交换次数,如果无解,则输出-1。一个整数占一行。
Sample Input
2
7
6
1 2
2 3
1 3
3 4
6 2
4 6
2 6
6
5
1 3
5 2
3 4
6 3
1 4
6 1
Sample Output
1
-1
Source
福建师范大学第五届程序设计竞赛
My Program
#include
<
iostream
>
#define
N 50005
using
namespace
std;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
typedef
struct
CARD
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int num;
struct CARD *next;
}
card;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
main()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int front,rear,queue[N];
int i,k,n,t,a,b,s1,s2,h[N];
card c[N],*p;
cin>>k;
while(k--)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
cin>>n;
cin>>t;
for(i=0;i<N;i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
h[i]=0;
c[i].next=NULL;
}
front=0;rear=1;
scanf("%d%d",&a,&b);
p=new card;
p->num=b;
p->next=NULL;
c[a].next=p;
p=new card;
p->num=a;
p->next=NULL;
c[b].next=p;
s1=a;s2=b;
queue[front]=t;
for(i=1;i<n;i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
scanf("%d%d",&a,&b);
p=new card;
p->num=b;
p->next=c[a].next;
c[a].next=p;
p=new card;
p->num=a;
p->next=c[b].next;
c[b].next=p;
}
while(front<rear)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
t=queue[front];
if(t==s1||t==s2)
break;
p=c[t].next;
while(p!=NULL)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if(h[p->num]==0)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
queue[rear++]=p->num;
h[p->num]=h[t]+1;
}
p=p->next;
}
front++;
}
if(t!=s1&&t!=s2)
printf("-1/n");
else
printf("%d/n",h[t]);
}
return 0;
}
YOYO's Note:
┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄它是华丽的分隔线
【题意简述】
有N张卡片,每张卡片上有两个数字,当两个数字中的任一数字与其他卡片相同时就可以交换卡片。我们的目的是通过最少的交换次数换到有幸运数字的卡片。
【粗略分析】
比较明显的,无向图求点到点的最短路径(?我不知道怎么说)。
为了查找方便,用链表形式存储无向图,每张卡片我都存两边,
然后从幸运数字开始倒回来用BFS搜索,同时记录第一次访问到时交换的次数,
当找到初始时的两个数字中的任一个或搜索完成时结束。
【C++源代码】
#include
<
iostream
>
#define
N 50005
using
namespace
std;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
typedef
struct
CARD
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int num;
struct CARD *next;
}
card;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
main()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int front,rear,queue[N];
int i,k,n,t,a,b,s1,s2,h[N];
card c[N],*p;
cin>>k;
while(k--)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
cin>>n;
cin>>t;
for(i=0;i<N;i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
h[i]=0;
c[i].next=NULL;
}
front=0;rear=1;
scanf("%d%d",&a,&b);
p=new card;
p->num=b;
p->next=NULL;
c[a].next=p;
p=new card;
p->num=a;
p->next=NULL;
c[b].next=p;
s1=a;s2=b;
queue[front]=t;
for(i=1;i<n;i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
scanf("%d%d",&a,&b);
p=new card;
p->num=b;
p->next=c[a].next;
c[a].next=p;
p=new card;
p->num=a;
p->next=c[b].next;
c[b].next=p;
}
while(front<rear)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
t=queue[front];
if(t==s1||t==s2)
break;
p=c[t].next;
while(p!=NULL)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if(h[p->num]==0)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
queue[rear++]=p->num;
h[p->num]=h[t]+1;
}
p=p->next;
}
front++;
}
if(t!=s1&&t!=s2)
printf("-1/n");
else
printf("%d/n",h[t]);
}
return 0;
}
【注意事项】
※ 好象没什么好注意的……这题好象很容易超时,记得大数据量的时候用scanf/printf..
【点评】
可以算是数据结构里图论的入门题吧。。