HOJ 1572 下沙小面的(2)

HOJ 1572 下沙小面的(2)

思路并不算太难,作为新手,我可能写得很拖沓

#include<iostream>
#include<algorithm>
#include<cstring>
#define MAX 99999999
using namespace std;
const int maxn = 30;
int k, n, a[maxn][maxn], b[8], c[8][8], c0[8];
//k为题目输入的城市数目多少,可能会重复
//n为需要到达的城市数目,不含重复
//a为所有城市之间的距离
//b为需要到达的城市在a中的下标
//c为需要到达的城市之间的距离
//c0为c中每个城市到达的次数
int cmp(int a, int b) {
	return a < b;
}

void dfs(int point, int &p, int temp, int &m) {
	if (temp == n) {
		for(int i  = 0; i <=n; i++)//必须每个城市都至少到达一次才算满足任务,否则p和m进行比较没有意义
			if (c0[i] == 0) return;
		if (p < m)//在每个目标城市都到达过的情况下看目前的路径是否比曾到达过的最短路径更小
			m = p;
		return;
	}
	for (int i = 0; i <= n; i++)
		if (i != point) {
			p += c[point][i];
			temp++;//已走过的城市加一
			c0[i]++;//i城市走过的次数加一
			dfs(i, p, temp, m);//下一步从i城启程
			c0[i]--;
			p -= c[point][i];
			temp--;
		}
			
}

int main() {
	int t, p, temp, minRoutine;
	while (cin >> t && t != 0) {
		n = 0;
		memset(a, 0, sizeof(a));
		memset(b, 0, sizeof(b));
		memset(c, 0, sizeof(c));
		memset(c0, 0, sizeof(c0));
		for (int i = 0; i < t; i++)
			for (int j = 0; j < t; j++)
				cin >> a[i][j];
		cin >> k;
		int i = 0, x = 0;
		while(1){//得到不含重复元素的数组b
			int kk;
			cin >> kk;
			x++;
			for (int j = 0; j < i; j++)
				if (kk == b[j])
					goto A;
			b[i++] = kk;
			n++;
		A:if (x == k)
			break;
			continue;
		}
		sort(b, b + n + 1, cmp);//加一是增加一个初始0点,排序
		p = 0;//尝试的路径长的
		minRoutine = MAX;//走完目的地的路径长度
		temp = 0;//以经尝试过的城市数量
		for(int i = 0; i <= n; i++)//找出需要用到的城市之间的路长存到c中
			for (int j = i; j <= n; j++) {
				c[i][j] = a[b[i]][b[j]];
				c[j][i] = a[b[j]][b[i]];
			}
		c0[0] = 1;
		dfs(0, p, temp, minRoutine);
		cout << minRoutine << endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值