Candies———最短路径, Dijkstra(用prioirty_queue实现 dijkstra + 堆的 POJ 3159 Candies)

博客围绕幼儿园糖果分配问题展开,孩子们会比较糖果数量,flymouse想在让大家满意的前提下,使自己和snoopy的糖果数差值最大。输入包含孩子数量和条件,可构建图。还提及Dijksra算法,以及用vector定义大小的方法。

Candies

Time Limit: 1500MS Memory Limit: 131072K
Total Submissions: 37835 Accepted: 10647

Description

During the kindergarten days, flymouse was the monitor of his class. Occasionally the head-teacher brought the kids of flymouse’s class a large bag of candies and had flymouse distribute them. All the kids loved candies very much and often compared the numbers of candies they got with others. A kid A could had the idea that though it might be the case that another kid B was better than him in some aspect and therefore had a reason for deserving more candies than he did, he should never get a certain number of candies fewer than B did no matter how many candies he actually got, otherwise he would feel dissatisfied and go to the head-teacher to complain about flymouse’s biased distribution.

snoopy shared class with flymouse at that time. flymouse always compared the number of his candies with that of snoopy’s. He wanted to make the difference between the numbers as large as possible while keeping every kid satisfied. Now he had just got another bag of candies from the head-teacher, what was the largest difference he could make out of it?

Input

The input contains a single test cases. The test cases starts with a line with two integers N and M not exceeding 30 000 and 150 000 respectively. N is the number of kids in the class and the kids were numbered 1 through N. snoopy and flymouse were always numbered 1 and N. Then follow M lines each holding three integers AB and c in order, meaning that kid A believed that kid B should never get over c candies more than he did.

Output

Output one line with only the largest difference desired. The difference is guaranteed to be finite.

Sample Input

2 2
1 2 5
2 1 4

Sample Output

5

Hint

32-bit signed integer type is capable of doing all arithmetic.

Source

POJ Monthly--2006.12.31, Sempr

1.Dijksra算法介绍:参考

2.本题从哪里看得出来是最短路径的题目?2比1 多的糖果数目不得超过5个,2和1就可以建立相应关系。1比2多的数目不得超过 4个,1和2也就可一建立关系,最后形成就是图。

3.vector<vector<candy> >cd(namx);vector定义大小namx:

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
#define namx 30006
struct candy
{
    int k;
    int w;
    bool operator<(const candy &c)const
    {
        return w>c.w;
    }
    candy(int kk,int ww):k(kk),w(ww){};
    candy(){};
};
priority_queue<candy>q;
vector<vector<candy> >cd(namx);//定义邻接表 
int n,m;
int vis[namx];
void dijkstra(vector<vector<candy> >&cd)
{

    
    candy p;
    p.k=1;
    p.w=0;//自己到自己的距离是0 
    q.push(p);
    while(!q.empty())
    {
        p=q.top();
        q.pop();
        if(vis[p.k])
            continue;
        vis[p.k]=1;
        if(p.k==n)  break;
        for(int i=0;i<cd[p.k].size();i++)
        {
            candy t;
            t.k=cd[p.k][i].k;
            if(vis[t.k]) continue;
            t.w=cd[p.k][i].w+p.w;
            q.push(t);
        }

    }
    printf("%d\n",p.w);
}
int main()
{
   //while(cin>>n>>m)
   //{
       cin>>n>>m;
       memset(vis,0,sizeof(vis));
       for(int i=1;i<=m;i++)
       {
           int a,b,c;
           scanf("%d%d%d",&a,&b,&c);
           cd[a].push_back(candy(b,c));
       }
       dijkstra(cd);
   //}
    return 0;

}

vector cd 用resize()函数定义大小:

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
#define namx 30006
struct candy
{
    int k;
    int w;
    bool operator<(const candy &c)const
    {
        return w>c.w;
    }
    candy(int kk,int ww):k(kk),w(ww){};
    candy(){};
};
priority_queue<candy>q;
vector<vector<candy> >cd;
int n,m;
int vis[namx];
void dijkstra(vector<vector<candy> >&cd)
{

    
    candy p;
    p.k=1;
    p.w=0;//自己到自己的距离是0 
    q.push(p);
    while(!q.empty())
    {
        p=q.top();
        q.pop();
        if(vis[p.k])
            continue;
        vis[p.k]=1;
        if(p.k==n)  break;
        for(int i=0;i<cd[p.k].size();i++)
        {
            candy t;
            t.k=cd[p.k][i].k;
            if(vis[t.k]) continue;
            t.w=cd[p.k][i].w+p.w;
            q.push(t);
        }

    }
    printf("%d\n",p.w);
}
int main()
{
   //while(cin>>n>>m)
   //{
       cin>>n>>m;
       memset(vis,0,sizeof(vis));
       cd.clear();
       cd.resize(n+1);//vector 中的resize()函数用来给vector预分配存储空间大小 
       for(int i=1;i<=m;i++)
       {
           int a,b,c;
           scanf("%d%d%d",&a,&b,&c);
           cd[a].push_back(candy(b,c));
       }
       dijkstra(cd);
   //}
    return 0;

}

 

 

C (gcc) 内存 612 / 65536 KB 用时 400 / 400 ms 状态 多种错误 分数 0 / 15 评测时间 2025/07/13 11:24:12 评测详情 测试点 提示 内存(KB) 用时(ms) 结果 得分 sample 308 1 答案错误 0 / 2 sample2 572 400 运行超时 0 / 2 sample3 612 1 答案错误 0 / 2 sample4 340 1 答案错误 0 / 3 sample5 500 2 答案错误 0 / 3 sample6 564 2 答案错误 0 / 3 提交代码 复制内容 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <stdio.h> #include <string.h> int main() { int n; scanf("%d", &n); int candies[10000], new_candies[10000]; for (int i = 0; i < n; i++) { scanf("%d", &candies[i]); } int rounds = 0; while (1) { int changed = 0; memset(new_candies, 0, sizeof(new_candies)); // 分配糖果 for (int i = 0; i < n; i++) { int give = candies[i] / 3; new_candies[i] += candies[i] - 2 * give; if (i == 0) { new_candies[n - 1] += give; new_candies[1] += give; } else if (i == n - 1) { new_candies[n - 2] += give; new_candies[0] += give; } else { new_candies[i - 1] += give; new_candies[i + 1] += give; } } // 检查是否稳定 for (int i = 0; i < n; i++) { 编译器输出 a.c: In function ‘main’: a.c:6:5: warning: ignoring return value of ‘scanf’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 6 | scanf("%d", &n); | ^~~~~~~~~~~~~~~ a.c:10:9: warning: ignoring return value of ‘scanf’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 10 | scanf("%d", &candies[i]);还是错的
最新发布
07-14
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值