1. 程式人生 > >ACM-售貨員難題

ACM-售貨員難題

ffffff iostream div printf 大於 urn 提高 eof .cpp

題目描述:售貨員的難題 某鄉有n個村莊(1< n < 20),有一個售貨員,他要到各個村莊去售貨,各村莊之間的路程s(0 < s < 1000)是已知的,且A村到B村與B村到A村的路大多不同。為了提高效率,他從商店出發到每個村莊一次,然後返回商店所在的村,假設商店所在的村莊為 1,他不知道選擇什麽樣的路線才能使所走的路程最短。請你幫他選擇一條最短的路。

輸入

村莊數n和各村之間的路程(均是整數)。

輸出

最短的路程

樣例輸入

3	{村莊數}
0 2 1	{村莊1到各村的路程}
1 0 2	{村莊2到各村的路程}
2 1 0	{村莊3到各村的路程}

樣例輸出

3

思路:就是DFS,但是減枝比較麻煩,還可以用DP。

這種寫法超時!!!
// 售貨員的難題.cpp : 定義控制臺應用程序的入口點。
//

#include "stdafx.h"

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;

const int MAX = 100;
int n, ans, vis[MAX], map[MAX][MAX];

void DFS(int
pos, int sum, int cnt) { //cout << "pos:" << pos << "\tsum:" << sum << "\tcnt:" << cnt << endl; if (cnt == n) { //cout << "===========end============:" << "sum:" << sum << "\tans:" << ans << endl; sum += map[pos][0
]; ans = min(sum, ans); return; } if (sum > ans) return; for (int i = 0; i < n; i++) { if (!vis[i]) { if (sum + map[pos][i] > ans) continue; vis[i] = 1; DFS(i, sum + map[pos][i], cnt + 1); vis[i] = 0; } } } int main() { memset(vis, 0, sizeof(vis)); memset(map, 0, sizeof(map)); ans = 0x3f3f3f3f; string str; cin >> n; getline(cin, str); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) cin >> map[i][j]; getline(cin, str); } vis[0] = 1; DFS(0, 0,1); cout << ans << endl; return 0; }

預處理一下就好了。

#include<iostream>
#include<cstdio>
using namespace std;
int n, g[20][20], r[20][20], f[20], ans = 0x7fffffff;
void Dfs(int now, int sum, int dis)
{
    if (dis + r[now][1] >= ans)return; //如果最小距離仍然大於最優解,直接減枝
    if (dis>ans)return;
    if (sum == n)
    {
        ans = min(ans, dis + g[now][1]);
        return;
    }
    for (int i = 1; i <= n; i++)
    if (f[i] == 0)
    {
        f[i] = 1; Dfs(i, sum + 1, dis + g[now][i]); f[i] = 0;
    }
}
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
        scanf("%d", &g[i][j]), r[i][j] = g[i][j];
    for (int k = 1; k <= n; k++)
    for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
        r[i][j] = min(r[i][j], r[i][k] + r[j][k]); //計算兩點之間的最小距離
    f[1] = 1;
    Dfs(1, 1, 0);
    printf("%d\n", ans);
    return 0;
}

ACM-售貨員難題