POJ 3159 Candies(差分约束+spfa+链式前向星)

题目链接:http://poj.org/problem?id=3159

题目大意:给n个人派糖果,给出m组数据,每组数据包含A,B,C三个数,意思是A的糖果数比B少的个数不多于C,即B的糖果数 - A的糖果数<=C 。

最后求n 比 1 最多多多少颗糖果。

解题思路:经典差分约束的题目,具体证明看这里《数与图的完美结合——浅析差分约束系统》

不妨将糖果数当作距离,把相差的最大糖果数看成有向边AB的权值,我们得到 dis[B]-dis[A]<=w(A,B)。看到这里,我们可以联想到求最短路时的松弛操作,

当if(dis[B]>dis[A]+w(A,B)因为要使A,B间满足dis[B]-dis[A]<=w(A,B)右要使差值最大,所以dis[B]=dis[A]+w(A,B)。

所以这题可以转化为最短路来求。注意:很坑,这题的spfa被卡了,要用栈才不会超时。

代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<stack>
 7 using namespace std;
 8 const int N=2e5+5;
 9
10 struct node{
11     int to,next,w;
12 }edge[N];
13
14 int n,m;
15 int idx,head[N];
16 //初始化
17 void init(){
18     idx=1;
19     memset(head,-1,sizeof(head));
20 }
21 //添加边
22 void addEdge(int u,int v,int w){
23     edge[idx].to=v;
24     edge[idx].w=w;
25     edge[idx].next=head[u];
26     head[u]=idx;
27     idx++;
28 }
29
30 int dis[N];
31 bool vis[N];
32 void spfa(int s){
33     memset(dis,0x3f,sizeof(dis));
34     dis[s]=0;
35     stack<int>sk;
36     sk.push(s);
37     while(!sk.empty()){
38         int k=sk.top();
39         sk.pop();
40         vis[k]=false;
41         for(int i=head[k];i!=-1;i=edge[i].next){
42             node t=edge[i];
43             //改变了松弛条件
44             if(dis[t.to]>dis[k]+t.w){
45                 dis[t.to]=dis[k]+t.w;
46                 if(!vis[t.to]){
47                     sk.push(t.to);
48                     vis[t.to]=true;
49                 }
50             }
51         }
52     }
53 }
54
55 int main(){
56     init();
57     scanf("%d%d",&n,&m);
58     for(int i=1;i<=m;i++){
59         int a,b,w;
60         scanf("%d%d%d",&a,&b,&w);
61         addEdge(a,b,w);
62     }
63     spfa(1);
64     printf("%d\n",dis[n]-dis[1]);
65     return 0;
66 }
时间: 2024-08-10 17:05:11

POJ 3159 Candies(差分约束+spfa+链式前向星)的相关文章

poj 3159 candies (差分约束 spfa+stack)

http://poj.org/problem?id=3159 题意:一个班有n个人 每人分到若干糖果 且u的糖果数不能比v少w个 求第1个人与第n个人最大数量差 照着模板spfa+queue果断tle了 之后照着题解说的把queue改成stack就过了 但是还不明白为什么会快 而且如果用数组直接模拟会比stl更快 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm>

UESTC30-最短路-Floyd最短路、spfa+链式前向星建图

最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的T-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据. 每组数据第一行是两个整数NN ,MM (N≤100N≤100 ,M≤10000M≤1000

最短路 SPFA()链式前向星

在极端情况下,图特别大,用邻接链表也会超空间限制,此时需要用到链式前向星来存图. 1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int inf = INT_MAX / 10; 5 const int num = ???; 6 struct Edge{ 7 int to, next, w;//edge[i]的i就是起点,终点to,权值w,相同起点的下一条边next 8 }edge[num]; 9 int n, m, cnt;

POJ 3159 Candies 差分约束

链接:http://poj.org/problem?id=3159 Candies Time Limit: 1500MS   Memory Limit: 131072K Total Submissions: 24852   Accepted: 6737 Description During the kindergarten days, flymouse was the monitor of his class. Occasionally the head-teacher brought the

POJ 3159 Candies(差分约束系统)

题目地址:POJ 3159 第一发差分约束的题..就当作最短路来做了...直接建图+spfa..不过我用的spfa+slf优化都超时..看了讨论区里的..把spfa换成栈就过了... 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include

POJ 3169 Layout (差分约束+SPFA)

Layout Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6832   Accepted: 3292 Description Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows numbered 1..N standing along a

单元最短路径算法模板汇总(Dijkstra, BF,SPFA),附链式前向星模板

一:dijkstra算法时间复杂度,用优先级队列优化的话,O((M+N)logN)求单源最短路径,要求所有边的权值非负.若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的. 设road[i][j]表示相邻的i到j的路长U集合存储已经求得的到源点最短路径的节点,S集合表示还没求得的节点dis[i]表示i到源节点(设为0)的最短路径vis[i]=1表示i节点在U集合中 刚开始dis[0]=0,vis[0]=1;dis[i]=maxn,vis[i]=0;for 1 to

最短路 spfa 算法 &amp;&amp; 链式前向星存图

推荐博客  https://i.cnblogs.com/EditPosts.aspx?opt=1 http://blog.csdn.net/mcdonnell_douglas/article/details/54379641 spfa  自行百度 说的很详细 spfa 有很多实现的方法  dfs  队列  栈  都可以 时间复杂度也不稳定 不过一般情况下要比bellman快得多 #include <stdio.h> #include <math.h> #include <st

链式前向星

重要的事情说三遍 明天不学会链式前向星我绝食三天