PAT甲级 1018 Public Bike Management

读题:
杭州有共享单车服务点。一个人可以在任意站点借一辆单车,在该城市的任意其他站点归还单车, PBMC持续管理所有站点的实时容量。如果一个站点是半饱和的,那么它是最佳的。如果它饱和或者空,PBMC会调整单车去满足最佳状态。并且所有路上的站点也要尽量达到最佳状态。当一个问题站点报告,PBMC总是选择最短路到达站点,如果多余一条最短路,选择从PBMC携带尽可能少的单车的路径。每个站点的最大容量为10。
输入:Cmax容量,N站点总数,Sp问题站点的下标(1,2……)PBMC的下标为0,M路的数目。第二行输入N个数,每个数表示该站点现有单车容量,用空格隔开;后面五行代表路径和时间。
输出:从PBMC调出的数量,路径,从站点带回的数目。如果路径不止一条,选择从各站点带回PBMC最少单车的路径,如果仍然相同,选择从PBMC带出最少单车的路径。

输入示例:

10 3 3 5
6 7 0
0 1 1
0 2 1
0 3 3
1 3 1
2 3 1

输出示例:

3 0->2->3 0

代码:

// // ConsoleApplicationA1018 Public Bike Management.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#define inf 0x3ffffff
using namespace std;

int Cmax, Sp, N, M;
int dis[510], m[510][510];
int weight[510];
bool visited[510] = { false };
vector<int>pre[510];
vector<int>temp, path;
int minneed = inf, minremain = inf;
void Dijkstra()
{
    int i, j, u;
    int minx;
    u = -1;
    for (i = 0; i <= N; i++)
    {
        minx = inf;//注意改行位置,不可以放在循环外面
        for (j = 0; j <= N; j++)
        {
            if (dis[j] < minx && !visited[j])
            {
                minx = dis[j];
                u = j;
            }
        }
        if (u == -1)return;
        visited[u] = true;
        for (j = 0; j <= N; j++)
        {
            if (!visited[j] && m[u][j] != inf)
            {

                if (dis[j] > dis[u] + m[u][j])
                {
                    dis[j] = dis[u] + m[u][j];
                    pre[j].clear();
                    pre[j].push_back(u);
                }
                else if (dis[j] == dis[u] + m[u][j])
                {
                    pre[j].push_back(u);
                }
            }
        }

    }
    for (i = 1; i <= N; i++)
    {
        for (j = 0; j < pre[i].size(); j++)
        {
            cout << pre[i][j] << " ";
        }
        cout << endl;
    }
}
void DFS(int v)
{
    int i;
    if (v == 0)
    {
        temp.push_back(v);
        int need = 0, remain = 0;
        for (i = temp.size() - 1; i >= 0; i--)
        {
            int id = temp[i];
            if (weight[id] >= 0)
            {
                remain += weight[id];
            }
            else
            {
                if (remain > abs(weight[id]))
                {
                    remain -= abs(weight[id]);
                }
                else
                {

                    need += abs(weight[id]) - remain;
                    remain = 0;
                }
            }
        }
        if (need < minneed)
        {
            minneed = need;
            minremain = remain;
            path = temp;
        }
        else if (need == minneed && remain < minremain)
        {
            minremain = remain;
            path = temp;
        }
        temp.pop_back();
        return;
    }
    temp.push_back(v);//将该顶点加入到路径中
    for (i = 0; i < pre[v].size(); i++)
    {
        DFS(pre[v][i]);
    }
    temp.pop_back();//返回后删除路径中的顶点
}

int main()
{

    int a, b, c;
    cin >> Cmax >> Sp >> N >> M;
    int i, j;
    for (i = 1; i <= N; i++)
    {
        cin >> weight[i];
        weight[i] -= Cmax / 2;
    }
    fill(dis, dis + N + 1, inf);
    //fill(m[0][0], m[0][0] +( N+1) * (N+1), inf); 
    for (i = 0; i <= N; i++)
    {
        for (j = 0; j <= N; j++)
        {
            m[i][j] = inf;
        }

    }
    for (i = 0; i < M; i++)
    {
        cin >> a >> b >> c;
        m[a][b] = m[b][a] = c;
    }
    dis[0] = 0;//初始化dis(start)=0
    for (i = 0; i <= N; i++)
    {
        m[i][i] = 0;
    }

    Dijkstra();
    DFS(Sp);
    cout << minneed << " ";
    for (i = path.size() - 1; i >= 0; i--)
    {
        cout << path[i];
        if (i > 0)cout << "->";
    }
    cout << " " << minremain;
    return 0;
}
/*
5 6 0 2
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1
*/



C3863 不可指定数组类型“int [510]”错误原因:
我定义了一个二维数组int m[510][510];而在使用fill对数组初始化时,并没有采用二维数组初始化的方式,而是写成了:fill(a, a + 510 * 510, inf);
正确写法应该是:fill(a[0], a[0] + 510 * 510, inf);(网络答案,但是验证后只会把第一行赋予inf),验证正确的结果为:

for(i=0;i<510;i++)
{
   fill(a[i],a[i]+510 inf);
)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值