1040 - The Traveling Judges Problem

A group of judges must get together to judge a contest held in a particular city, and they need to figure out the cheapest way of renting cars in order to get everyone to the contest. They observed that it might be cheaper if several judges share a rental car during all or part of the trip, thus reducing the overall cost. Your task is to identify the routes the judges should take in order to minimize the total cost of their car rentals.


We will make the following assumptions:

  • The cost of a rental car is proportional to the distance it is driven. There are no charges for more than one occupant in the car, fuel, insurance, or leaving the car in a city other than that in which it was rented.
  • All rental cars are billed at the same rate per mile.
  • A rental car can accommodate any number of passengers.
  • At most one road directly connects any pair of cities. Each road is two-way and has an integer length greater than zero.
  • There is at least one route from every judge's starting city to the city in which the contest is held.
  • All judges whose routes to the contest take them from or through the same city travel from that city to the contest together. (A judge might arrive at a city in one car and leave that city in a different car.)

Input 

The input contains several test cases. Each test case includes a route map, the destination city where the contest is being held, and the cities where the judges are initially located.


Each case appears in the input as a list of integers separated by blanks and/or ends of lines. The order and interpretation of the integers in each case is as follows:

  • NC-the number of cities that appear in the route map; this will be no larger than 20.
  • DC-the number of the destination city, assuming the cities are numbered 1 to NC.
  • NR-the number of roads in the route map. Each road connects a distinct pair of cities.
  • For each of the NR roads, three integers C1C2, and DISTC1 and C2 identify two cities connected by a road, and DIST gives the distance between these cities along that road.
  • NJ-the number of judges. This number will be no larger than 10.
  • NJ-integers, one for each judge each of these is a city number identifying the initial location of that judge.


The data for the last case will be followed by a line consisting of the integer `-1'.

Output 

For each test case, display the case number (1, 2,...) and the shortest total distance traveled by the rental cars conveying the judges to the contest. Then display the list of routes used by the judges, each route on a separate line, in the same order as the ordering of starting cities given in the input. Each route consists of the cities that the corresponding judge must visit, listed in the order in which they are visited, starting with the judge's starting city and ending with the contest city. Any other cities along the route are listed in the order in which they are visited during the judge's travels. Separate the numbers in the route with `-', and precede each route by three spaces.


If multiple sets of routes have the same minimum distance, choose a set that requires the fewest number of cities. If several sets of cities of the same cardinality may be used, choose the set that comes lexicographically first when ordered by city number (e.g., {2, 3, 6} rather than {2, 10, 5}). If multiple routes are still available, output any set of routes that meets the requirements.


Follow the format of the sample output.

Sample Input 

5
3 5                  
1 2 1              
2 3 2              
3 4 3              
4 5 1              
2 4 2              
2
5
1                
                   
4                   
4 3                   
1 3 1               
2 3 2               
3 4 2               
2                   
1
2                 
                    
3
3 3               
1 2 2               
1 3 3               
2 3 1               
2
2
1               
                    
-1

Sample Output 

Case 1: distance = 6 
   5-4-2-3 
   1-2-3
 
Case 2: distance = 5 
   1-3-4 
   2-3-4 
 
Case 3: distance = 3 
   2-3 
   1-2-3




#include<stdio.h>
#include<string.h>
#include<stdlib.h>
const int MaxC=20;
const int MaxJ=10;
int cases,NC,NJ,T,DC,map,best_map,ans,i,k;
int road[MaxC][MaxC],judges[MaxJ],fa[MaxC];
bool init()
{
	int NR,i,C1,C2;
	scanf("%d",&NC);
	if(NC==-1)
		return false;
	scanf("%d",&DC);
	DC--;
	T=1<<DC;
	scanf("%d",&NR);
	memset(road,0,sizeof(road));
	ans=1000;
	for(i=0;i<NR;i++)
	{
		scanf("%d %d",&C1,&C2);
		C1--;C2--;
		scanf("%d",&road[C1][C2]);
		road[C2][C1]=road[C1][C2];
		ans+=road[C1][C2];
	}
	scanf("%d",&NJ);
	for(i=0;i<NJ;i++)
	{
		scanf("%d",&judges[i]);
		judges[i]--;
		T+=1<<judges[i];
	}
	return true;
}

void check(int map)
{
	int i,j,k,sum,min;
	int d[MaxC];
	for(i=0;i<MaxC;i++)
		d[i]=-2;
	d[DC]=-1;
	for(i=0;i<MaxC;i++)
		if(((1<<i)&map)&&road[DC][i])
		{
			d[i]=road[DC][i];
			fa[i]=DC;
		}
	sum=0;
	while(1)
	{
		min=ans+10;
		for(i=0;i<MaxC;i++)
			if(d[i]>0&&d[i]<min)
			{
				min=d[i];
				k=i;
			}
		if(min>ans)
			break;
		sum+=min;
		d[k]=-1;
		for(i=0;i<MaxC;i++)
			if((1<<i)&map&&road[k][i])
				if(d[i]==-2||d[i]>road[k][i])
				{
					d[i]=road[k][i];
					fa[i]=k;
				}
	}
	for(i=0;i<MaxC;i++)
		if(((1<<i)&map)&&d[i]==-2)
			return;
	if(sum<ans)
	{
		ans=sum;
		best_map=map;
	}
	else if(sum==ans)
	{
		j=0;k=0;
		for(i=0;i<MaxC;i++)
		{
			if((1<<i)&best_map) j++;
			if((1<<i)&map) k++;
		}
		if(j>k)
		{
			best_map=map;
			return;
		}
		if(j<k)
			return;
		for(i=0;i<MaxC;i++)
		{
			if(((1<<i)&best_map)&&!((1<<i)&map))
				return;
			if(!((1<<i)&best_map)&&((1<<i)&map))
			{
				best_map=map;
				return;
			}
		}
	}
}

int main()
{
	cases=0;
	while(init())
	{
		best_map=0;
		for(map=0;map<(1<<NC);map++)
			if((map&T)==T)
				check(map);
		printf("Case %d: distance = %d\n",++cases,ans);
		check(best_map);
		for(i=0;i<NJ;i++)
		{
			printf("   %d",judges[i]+1);
			k=judges[i];
			while(k!=DC)
			{
				printf("-%d",fa[k]+1);
				k=fa[k];
			}
			printf("\n");
		}
		printf("\n");
	}
	return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值