spfa+多重约束

2024-09-05 21:32
文章标签 spfa 多重 约束

本文主要是介绍spfa+多重约束,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

普通的spfa只是用来求单源最短路(也就是边权和最小),是通过不断松弛边权来求的。

但是在一些情况需要求点权和最大或最小的情况(或者是其他的约束条件)

我们只需要根据条件加几个约束条件就行

以下是例题:


L2-001. 紧急救援

时间限制:200 ms
内存限制:65536 kB
代码长度限制:8000 B

作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。

输入格式:

输入第一行给出4个正整数N、M、S、D,其中N(2<=N<=500)是城市的个数,顺便假设城市的编号为0~(N-1);M是快速道路的条数;S是出发地的城市编号;D是目的地的城市编号。第二行给出N个正整数,其中第i个数是第i个城市的救援队的数目,数字间以空格分隔。随后的M行中,每行给出一条快速道路的信息,分别是:城市1、城市2、快速道路的长度,中间用空格分开,数字均为整数且不超过500。输入保证救援可行且最优解唯一。

输出格式:

第一行输出不同的最短路径的条数和能够召集的最多的救援队数量。第二行输出从S到D的路径中经过的城市编号。数字间以空格分隔,输出首尾不能有多余空格。

输入样例:
4 5 0 3
20 30 40 10
0 1 1
1 3 2
0 3 3
0 2 2
2 3 2
输出样例:
2 60
0 1 3


题目链接:https://www.patest.cn/contests/gplt/L2-001

连接已挂

这道题求的是在边权和最小的情况下求点权和最大的情况,随便在把这种情况的路径打印出来;

代码如下

#include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std;
const int INF =505;struct node
{int to,w,next;	
};
node edge[INF * INF];
int head[INF];
int pointW[INF];
int n,m,st,end;
/*/*
4 5 0 3
20 30 40 10
0 1 1
1 3 2
0 3 3
0 2 2
2 3 22 60
0 1 3
*/
int Outpath(int k);		//输出路径 int path[INF];			//用类似链表的形式存路径int main()
{fill(head,head + INF, -1);path[st]  = -1;scanf("%d %d %d %d",&n,&m,&st,&end);for(int i = 0; i < n; i++)scanf("%d",&pointW[i]);				//用来存点权 //用链式前向星来存图--------------------------- for(int i =1; i <= 2*m; i++){int a,b,c;scanf("%d %d %d",&a,&b,&c);edge[i].to = b, edge[i].w =c, edge[i].next = head[a];head[a] = i;i++;edge[i].to =a, edge[i].w =c, edge[i].next = head[b] ;head[b] = i;}//分别用来存边权和,每个点的标记情况,和点权和 int dis[INF], book[INF],ans[INF];//初始化-------------------------------- fill(dis,dis + INF,9999999);dis[st] = 0;fill(book,book + INF, 0);book[st] = 1;fill(book, book + INF, 0);ans[st] = pointW[st];queue <int> que;que.push(st);while(!que.empty()){int now = que.front();book[now] = 0;que.pop();for(int k = head[now]; k != -1; k =edge[k].next){//约束条件一,寻找边权和最大的情况 if(dis[edge[k].to] > dis[now] + edge[k].w){dis[edge[k].to] = dis[now] + edge[k].w;ans[edge[k].to] = pointW[edge[k].to] + ans[now];path[edge[k].to] = now;if(book[edge[k].to] == 0){book[edge[k].to] = 1;que.push(edge[k].to);}}//约束条件二,在存在多个边权和相等的情况下求点权和最大 else if(dis[edge[k].to] == dis[now] + edge[k].w){if(ans[edge[k].to] < pointW[edge[k].to] +ans[now] ){ans[edge[k].to] = pointW[edge[k].to] + ans[now];path[edge[k].to] = now;}}}}printf("%d %d\n",dis[end],ans[end]);int k = end;Outpath( k);printf("%d\n",k);return 0;	
}
int Outpath(int k)
{if(path[k] == -1)return k;else{printf("%d ",Outpath(path[k]));return k;}
}

这篇关于spfa+多重约束的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1140114

相关文章

SQL中的外键约束

外键约束用于表示两张表中的指标连接关系。外键约束的作用主要有以下三点: 1.确保子表中的某个字段(外键)只能引用父表中的有效记录2.主表中的列被删除时,子表中的关联列也会被删除3.主表中的列更新时,子表中的关联元素也会被更新 子表中的元素指向主表 以下是一个外键约束的实例展示

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

poj 1511 Invitation Cards(spfa最短路)

题意是给你点与点之间的距离,求来回到点1的最短路中的边权和。 因为边很大,不能用原来的dijkstra什么的,所以用spfa来做。并且注意要用long long int 来存储。 稍微改了一下学长的模板。 stack stl 实现代码: #include<stdio.h>#include<stack>using namespace std;const int M

poj 3159 (spfa差分约束最短路) poj 1201

poj 3159: 题意: 每次给出b比a多不多于c个糖果,求n最多比1多多少个糖果。 解析: 差分约束。 这个博客讲差分约束讲的比较好: http://www.cnblogs.com/void/archive/2011/08/26/2153928.html 套个spfa。 代码: #include <iostream>#include <cstdio>#i

poj 3169 spfa 差分约束

题意: 给n只牛,这些牛有些关系。 ml个关系:fr 与 to 牛间的距离要小于等于 cost。 md个关系:fr 与 to 牛间的距离要大于等于 cost。 隐含关系: d[ i ] <= d[ i + 1 ] 解析: 用以上关系建图,求1-n间最短路即可。 新学了一种建图的方法。。。。。。 代码: #include <iostream>#include

poj 3255 次短路(第k短路) A* + spfa 或 dijkstra

题意: 给一张无向图,求从1到n的次短路。 解析: A* + spfa 或者 dijkstra。 详解见上一题:http://blog.csdn.net/u013508213/article/details/46400189 本题,spfa中,stack超时,queue的效率最高,priority_queue次之。 代码: #include <iostream>#i

poj 2449 第k短路 A* + spfa

poj 2449: 题意: 给一张有向图,求第k短路。 解析: A* + spfa。 一下转自:http://blog.csdn.net/mbxc816/article/details/7197228 “描述一下怎样用启发式搜索来解决K短路。 首先我们知道A*的基础公式:f(x)=g(x)+h(x);对h(x)进行设计,根据定义h(x)为当前的x点到目标点t所需要的实际距

多重背包转换成0-1背包

http://acm.hdu.edu.cn/showproblem.php?pid=2191 多重背包特点: 一种物品有C个(既不是固定的1个,也不是无数个) 优化的方法: 运用神奇的二进制,进行物品拆分,转化成01背包 物品拆分,把13个相同的物品分成4组(1,2,4,6) 用这4组可以组成任意一个1~13之间的数! 原理:一个数总可以用2^

POJ 1364差分约束

给出n个变量,m个约束公式 Sa + Sa+1 + .... + Sa+b < ki or > ki ,叫你判断是否存在着解满足这m组约束公式。 Sa + Sa+1   +   .+ Sa+b =  Sum[a+b] - Sum[a-1]  . 注意加入源点n+1 。 public class Main {public static void main(Strin

创建表时添加约束

查询表中的约束信息: SHOW KEYS FROM 表名; 示例: 创建depts表包含department_id该列为主键自动增长,department_name列不允许重复,location_id列不允许有空值。 create table depts(department_id int primary key auto_increment,department_name varcha