1084:XX开公司<回溯>

本文介绍了一个关于任务分配的问题,目标是最小化完成所有工作的总时间。通过递归回溯算法来寻找最优解,并提供了一个具体的代码实现案例。
2020年,xx开了一家拥有N个员工的大公司。每天,xx都要分配N项工作给他的员工,但是,由于能力的不同,每个人对处理相同工作所需要的时间有快有慢。众所周知,xx是一个非常重视效率的人,他想知道该如何分配工作,才能使得完成所有工作的时间总和最小(每个员工只可以被分配到一个工作)。但是我们也都知道xx不是一般的懒,所以xx找到了你,请你拯救一下xx吧!
有多组测试数据。(不超过50组)
对于每组测试数据:
第一行输入一个整数N,代表有N员工,员工编号从1到N。(1 <= N <= 10,N >= 8的数据只有3组) 
接着输入一个N*N的二维矩阵task[N][N],task[i][j]指的是第i项工作如果由j号员工完成所需要的时间。(0 <= task[i][j] <= 1000)
输出结果包括一个整数,代表所需要的最少时间(求和)。
6
10 11 12 11 9 11
11 9 10 13 11 12
12 10 11 10 13 9
9 14 9 10 10 11
10 10 9 11 12 11
10 7 10 10 10 8
54
#include<iostream>
#include<cstdio>
using namespace std;
int n,cost=0;
int x[100],c[100][100];
void work(int i,int count){
    if(i>n&&count<cost){
        cost=count;
        return ;
    }
    if(count<cost)
        for(int j=1;j<=n;j++)
            if(x[j]==0){
                x[j]=1;
                work(i+1,count+c[i][j]);
                x[j]=0;
            }
}
int main ()
{
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++)
                scanf("%d",&c[i][j]);
            x[i]=0;
            cost+=c[i][i];
        }
        work(1,0);
        printf("%d\n",cost);
    }
    return 0;
}

洛谷的 P1491 代码实现有问题,请在原代码上修改并注释。 #include <bits/stdc++.h> using namespace std; struct edge { int v; double w; }; struct node { int x, y; }; int n, m; vector<int> pre, pass; vector<double> dist; vector<vector<edge>> mp; vector<bool> st; vector<node> a; double ans = 0x3f3f3f3f; bool operator<(pair<double, int> a, pair<double, int> b) { return a.first < b.first; } void d(int xx, int yy) { for (int i = 0; i <= n; i++) { dist[i] = DBL_MAX; } dist[1] = 0; priority_queue<pair<double, int>> q; q.push({0, 1}); st = vector<bool>(n + 1, 0); while (!q.empty()) { int u = q.top().second; q.pop(); if (st[u]) continue; st[u] = 1; for (auto y : mp[u]) { int v = y.v; double w = y.w; if ((u == xx && v == yy) || (u == yy && v == xx)) continue; if (dist[v] > dist[u] + w) { dist[v] = dist[u] + w; q.push({-dist[v], v}); if (xx == -1 && yy == -1) pre[v] = u; // 很多遍 // 路径记录 第一次的原始的 } } } } double distance(double x1, double y1, double x2, double y2) { return hypot(x2 - x1, y2 - y1); } int main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); cin >> n >> m; dist.resize(n + 1, 0x3f3f3f3f); a.resize(n + 1); mp.resize(n + 1); st.resize(n + 1); pre.resize(n + 1); for (int i = 0; i < n; i++) { int x, y; cin >> x >> y; a[i + 1] = {x, y}; } for (int i = 1; i <= m; ++i) { int u, v; cin >> u >> v; double w = distance(a[u].x, a[u].y, a[v].x, a[v].y); mp[u].push_back({v, w}); mp[v].push_back({u, w}); } d(-1, -1); for (int i = pre[n]; i != -1; i = pre[i]) { // pass.push_back(i); d(i, pre[i]); ans = min(ans, dist[n]); if (i == 1) break; } // for (int i = 0; i < pass.size() - 1; i++) { // if (pass[i] == -1 || pass[i + 1] == -1) // continue; // int dx = pass[i], dy = pass[i + 1]; // d(dx, dy); // ans = min(ans, dist[n]); // } cout << fixed << setprecision(2) << ans; return 0; }
10-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值