Airfare

Mr. Liu has to travel various offices abroad to assist branches of each place. But he has a problem. The airfare would be real high as all offices he has to visit are in foreign countries. He wants to visit every location only one time and return home with the lowest expense.
Help this company-caring man calculate the lowest expense.

Time limit : 1 second (java : 2 seconds)

Input format


Several test cases can be included in the inputs. T, the number of cases is given in the first row of the inputs. After that, the test cases as many as T (T ≤ 30) are given in a row.
N, the number of offices to visit is given on the first row per each test case. At this moment, No. 1 office is regarded as his company (Departure point). (1 ≤ N ≤ 12)
Airfares are given to move cities in which branches are located from the second row to N number rows. I.e. jth number of ith row is the airfare to move from ith city to jth city. If it is impossible to move between two cities, it is given as zero.

Output format

Output the minimum airfare used to depart from his company, visit all offices, and then return his company on the first row per each test case.

Example of Input

2
5
0 14 4 10 20
14 0 7 8 7
4 5 0 7 16
11 7 9 0 2
18 7 17 4 0
5
9 9 2 9 5
6 3 5 1 5
1 8 3 3 3
6 0 9 6 8
6 6 9 4 8

Example of Output

30

18


C solution

#include <stdio.h>
#include <string.h>
#include <limits.h>

int data[13][13];
int visited[13];
int N;
int cost, count, finalCost;

void func(int i);


int main(void)
{
	int tc, T;
	
	setbuf(stdout, NULL);

	scanf("%d", &T);
	for(tc = 0; tc < T; tc++)
	{
		int i,j,k;
		scanf("%d", &N);
		for(i=1;i<=N;i++)
			for(j=1;j<=N;j++)
				scanf("%d", &data[i][j]);
				
		memset(visited, 0, sizeof(visited));
		count=0;
		cost=0;
		finalCost=INT_MAX;
		func(1);
		
		printf("%d\n", finalCost);
		
	}

	return 0;
}

void func(int i)
{
	int j, k;
	visited[i]=1;
	count++;
	
	if(count==N&&data[i][1]!=0)
	{
		if(finalCost>cost+data[i][1])
			finalCost = cost+data[i][1];
		
		count--;
		visited[i]=0;
		return;
	}

	for(j=1;j<=N;j++)
		if(!visited[j]&&data[i][j])
		{
			if(data[i][j]+cost>finalCost)continue;
			cost+=data[i][j];
			func(j);
			cost-=data[i][j];
		}
	
	count--;
	visited[i]=0;
	return;
}
// In Practice, You should use the statndard input/output
// in order to receive a score properly.
// Do not use file input and output. Please be very careful. 

#include <stdio.h>

#define MAX_SIZE 13
#define true 1
#define false 0

typedef unsigned int uint32;

#define INF 0xFFFFFFFF

uint32 adj[MAX_SIZE][MAX_SIZE];
unsigned char  visited[MAX_SIZE];
uint32 final_cost;

uint32 size;

void TSP_nfact(uint32 cost,uint32 edg_budget,uint32 src)
{
	int i;

	if(edg_budget == size-1)
	{
		if(adj[src][0]!=0)
		{
			cost = cost + adj[src][0];
			if(cost < final_cost)
				final_cost = cost;
		}
		return;
	}

        visited[src] = true;
	for( i = 0 ; i <size; i++)
	{
		if(visited[i] == false && adj[src][i] != 0 && (cost + adj[src][i] < final_cost ))
		{
	
			TSP_nfact((cost + adj[src][i]),edg_budget+1,i);
		}
	}
       visited[src] = false;

}

int main(void)
{
	int tc, T;
	int i,j,N;

	
   // freopen("air_fare.txt", "r", stdin);


	setbuf(stdout, NULL);

	scanf("%d", &T);
	//T = 2;
	for(tc = 0; tc < T; tc++)
	{
		scanf("%d",&N);

		for(i = 0 ; i <N; i++)
		{
                      visited[i] = 0;
			for( j = 0; j <N; j++)
			{
				scanf("%d",&adj[i][j]);
			}
		}

		final_cost = INF;
		size  = N;
		//visited[0] = true;

                    //  if(size <12)
		TSP_nfact(0,0,0);

		// Print the answer to standard output(screen).

		printf("%u\n",final_cost);
		
	}

	return 0;//Your program should return 0 on normal termination.
}

C++

#include <cstdio>
#include <iostream>

using namespace std;
int N;
int data[13][13];
int min_sum = 65535;
int final[13] = {0};
void find_min_fare(int point, int fare, int num){
	int i;
	if(fare >= min_sum)
		return;
	if(num == N){
		if(data[point][0]!=0 && min_sum > fare + data[point][0])
			min_sum = fare + data[point][0];
		return;
	}
	final[point] = 1;
	for(i = 1 ; i < N ; ++i){
		if(!final[i] && data[point][i] != 0){
			find_min_fare(i,data[point][i]+fare,num+1);
		}
	}
	final[point] = 0;
}

int main(int argc, char** argv)
{
	int tc, T;

	cin >> T;
	for(tc = 0; tc < T; tc++)
	{
		/**********************************
		*  Implement your algorithm here. *
		***********************************/
		cin >> N;
		for(int i = 0 ; i  < N ; i++){
			for(int j = 0 ; j < N; j++){
				cin >> data[i][j];
			}
		}
		find_min_fare(0,0,1);
		cout<<min_sum<<endl;
		min_sum = 65535;
		for(int i = 0 ; i < N ; i++)
			final[i] = 0;
		// Print the answer to standard output(screen).
		
	}

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值