习题 54: 邮递员★★★

/*
习题 54: 邮递员★★★

 
 题目描述:
 有一个邮递员要在n个城市之间来回送信。但有的城市之间有大路相连
 而有的没有路。现在要由一个城市到另一个城市送信,中途最少要经过
 多少个其它的城市呢?
 
   输入:
   第一行是n,k(1<=n<=10000, 1<=k<=20000),接下来就是k行。
   这k行每行有两个数a,b(1 <= a,b <= n),表示城市a和b之间有大路
   k行以后就是两个数p和q。
   当n,k输入都为0的时候结束。
  
  输出:
  输出从城市p到城市q之间最少要经过的其它的城市的数目。
  如果p和q之间不连通则输出"No solution"
  
    样例输入:
    6 6
    1 4
    1 2
    2 3
    3 4
    5 4
    5 6
    1 6
    0 0
   
   样例输出:
   2
   
难度:Normal
*/
#include "StdAfx.h"
#include <iostream>
#include <cassert>
#define MAX_DIRECTION 40000 //总共可能有40000条有向路线
#define MAX_CITY_NUMS 10001 //邻接表表头数量
#define QUEUE_SIZE 10001    //队列容量
#define TABLE_SIZE 10001    //表容量
#define UNVISITED 0          //未访问节点,但是对应节点的距离可以是已知的
#define VISITED 1
//分配节点
//#define MALLOC_NODE(p) (p) = &space[CityNodeCount++]
#define INFINITY  1001  //无穷远
//临接矩阵用
typedef struct adjacent
{
 int city_num;
 struct adjacent *next;
} CityNode;

//全局数组,模拟heap,降低系统开销
CityNode space[MAX_DIRECTION];
//space用掉了多少空间;
int CityNodeCount;

//邻接表表头
CityNode head[MAX_CITY_NUMS];
//邻接表中实际节点个数
int real_city_num;

//节点队列
CityNode* queue[QUEUE_SIZE];
int queue_head,queue_end;

//无权最短路径配置表
int table[TABLE_SIZE][2];//known, dv, pv(discard)

void initialize(int n)
{
 int i;
 CityNodeCount = 0;
 real_city_num = n;
 //memset(head, 0, MAX_CITY_NUMS * sizeof(void(*)));//初始化邻接表表头
 for( i = 0; i < MAX_CITY_NUMS;)
 {
  head[i].next = NULL;
  head[i].city_num = ++i;
 }
 memset(queue, 0, QUEUE_SIZE * sizeof(void(*)));//初始化队列
 queue_head = queue_end = 0;
 memset(space, 0, MAX_DIRECTION * sizeof(CityNode));// 初始化heap

 for(i = -1; ++i < TABLE_SIZE;)
 {
  table[i][0] = UNVISITED;   //known
  table[i][1] = INFINITY; //distance from start point
  //table[i][2] = 0;  //previous point,discard
 }

}

//将数据插入邻接表
void insert_adjacent(int city_start, int city_end)
{
 CityNode *tmp;
 tmp = head[city_start].next;
 //MALLOC_NODE(head[city_start]);
 head[city_start].next = &space[CityNodeCount++];
 head[city_start].next->next = tmp;
 //assert(head[city_start] == &space[CityNodeCount - 1]);
 head[city_start].next->city_num = city_end;
 
 tmp = head[city_end].next;
 //MALLOC_NODE(head[city_end]);
 head[city_end].next = &space[CityNodeCount++];
 head[city_end].next->next = tmp;
 head[city_end].next->city_num = city_start;
}
//搜索并输出结果
void search(int start_city, int end_city)
{
 int cur_distance;
 CityNode *tmp;
 
 tmp = &head[start_city];
 queue[queue_end++] = tmp;
 if(start_city == end_city)
 {
  printf("%d/n",0);
  return;
 }
 /*
 table[start_city][0] = VISITED;*/
 table[start_city][1] = 0;//distance
 cur_distance = 0;
 //printf("search entered!first city is %d/n",start_city);
 do
 {
  tmp = queue[queue_head];
  //printf("%d out queue/n",tmp->city_num);
  queue[queue_head] = NULL;
  queue_head =(queue_head + 1) % QUEUE_SIZE;
  table[tmp->city_num][0] = VISITED;//known
  //table[tmp->city_num][1] = cur_distance;
  cur_distance = table[tmp->city_num][1] + 1;
  tmp = tmp->next;
  while(tmp)//adjacent
  {
   //printf("city %d->",tmp->city_num);
   if(table[tmp->city_num][1] == INFINITY)
   {
    //if(table[tmp->city_num][1] == INFINITY)
    table[tmp->city_num][1] = cur_distance;//distance
    //enqueue
    queue[queue_end] = &head[tmp->city_num];
    //printf("/n    city %d enqueue /n",tmp->city_num);
    queue_end = (queue_end + 1) % QUEUE_SIZE;
   }
   tmp = tmp->next;
  }  
  //printf("/nqueue_head = %d,queue_end = %d/n",queue_head,queue_end);
  if(queue_head == queue_end)
   break;
  else
   continue;
 } while (true);

 //printf("search end!/n");
 if(INFINITY == table[end_city][1])
 {
  printf("No solution/n");
 }else
 {
  printf("%d/n",table[end_city][1]-1);
 }
 //printf("out search!/n");
}
int main(void)
{
 int n,k,j;
 int city_start, city_end;
 while(scanf("%d%d",&n,&k)!=EOF)
 {
  if(n == 0 && k == 0)
   break;
  initialize(n);
  for(j = -1; ++j < k;)
  {
   //printf("process 0/n");
   scanf("%d%d",&city_start,&city_end);
   //printf("process 1/n");
   insert_adjacent(city_start,city_end);
   //printf("process 2/n");
  }
  
  scanf("%d%d",&city_start,&city_end);
  search(city_start,city_end);
 }
 return 0;
}
/*

79690

Name: " younthu" Problem ID " 54"
Submit Time: 2008/10/03-09:01

G++: Compile OK

Test  1:    Accepted    Time = 0 ms
Test  2:    Accepted    Time = 0 ms
Test  3:    Accepted    Time = 10 ms
--------------------------------
Problem ID     54
Test Result    Accepted
Total Time     10 ms
Total Memory   668 Kb / 2000 Kb
Code Length    2725 Bytes


*/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值