ShortestPath:Layout(POJ 3169)(差分约束的应用)
题目大意:有N头牛,编号1-N,按编号排成一排准备吃东西,有些牛的关系比较好,所以希望他们不超过一定的距离,也有一些牛的关系很不好,所以希望彼此之间要满足某个关系,牛可以挤在同一个位置上,现在给出N个牛的信息,问你能否实现一种排列方案,使得d[1]到d[N]最大?如果不存在输出-1,无限大输出-2
这一题看上去挺难的,但是如果你知道差分约束原理,这一题似乎还是挺简单的。
差分约束的原理是:存在任意线性方程,满足d[A]+c>=d[B],就可以表示为图的最短路形式,方程可以表示为A->B,权值为c的边,最后任意点之间距离之差的最大值,即为两点之间的最短距离。
在最短路的算法中,恒有d[u]+w>=d[s](s是源点,w是权值,u是除了s的任意点),则d[u]-d[s]的最大值即为s-u的最短路经长。
回到题目上来,那么这一题事实上蕴含了三个线性方程:
1.d[i+1]>=d[i](按照编号排序)
2.d[BL]-d[AL]<=DL->->->d[AL]+DL>=d[BL]
3.d[BD]-D[AD]>=DD->->->d[BD]-DD>=d[AD]
则我们只用把这些边表示出来算最短路径就可以了,这一题有负值边,用Bellman_Ford或者SPFA就可以了
Bellman_Ford:
#include <iostream>
#include <functional>
#include <algorithm>
#define MAX 0x7f7f7f7f using namespace std; typedef int Positon;
typedef struct least_
{
Positon A;
Positon B;
int cost;
}Relation; static Relation L_Set[],M_Set[];
static int dist[]; void Bellman_Ford(const int, const int, const int); int main(void)
{
int cows_sum, ML, MD;
while (~scanf("%d%d%d", &cows_sum, &ML, &MD))
{
for (int i = ; i < ML; i++)
scanf("%d%d%d", &L_Set[i].A, &L_Set[i].B, &L_Set[i].cost);
for (int i = ; i < MD; i++)
scanf("%d%d%d", &M_Set[i].A, &M_Set[i].B, &M_Set[i].cost);
Bellman_Ford(cows_sum, ML, MD);
}
return ;
} void Bellman_Ford(const int cows_sum, const int ML, const int MD)
{
memset(dist, 0x7f, sizeof(dist));
dist[] = ;//到自己肯定是最短的 for (int i = ; i <= cows_sum; i++)
{
for (int i = ; i + <= cows_sum; i++)
if (dist[i + ] < MAX)//差分约束方程d[i+1]>=d[i]
dist[i] = min(dist[i], dist[i + ]);
for (int i = ; i < ML; i++)//差分约束方程d[AL]+DL>=d[BL]
if (dist[L_Set[i].A] < MAX)
dist[L_Set[i].B] = min(dist[L_Set[i].B], dist[L_Set[i].A] + L_Set[i].cost);
for (int i = ; i < MD; i++)//差分约束方程d[BD]-DD>=d[AD]
if (dist[M_Set[i].B] < MAX)
dist[M_Set[i].A] = min(dist[M_Set[i].A], dist[M_Set[i].B] - M_Set[i].cost);
} int ans = dist[cows_sum];
if (dist[] < )
printf("-1\n");
else if (dist[cows_sum] == MAX)
printf("-2\n");
else printf("%d\n", ans);
}
SPFA:
#include <iostream>
#include <functional>
#include <algorithm>
#include <queue>
#define MAX 0x7f7f7f7f using namespace std; typedef int Position;
typedef struct least_
{
int next;
Position to;
int cost;
}Edge_Set; static Edge_Set edge[];//存边
static Position Head[];
static int dist[];
static int out[];//记录出去多少次
static bool used[];//记录是否在队内 void SPFA(const int, const int); int main(void)
{
int cows_sum, ML, MD, i, cost, edge_sum;
Position from, to;
while (~scanf("%d%d%d", &cows_sum, &ML, &MD))
{
memset(Head, -, sizeof(Head)); memset(dist, 0x7f, sizeof(dist)); memset(used, , sizeof(used)); memset(out, , sizeof(out));
edge_sum = ;
//读入邻接表
for (i = ; i < ML; i++)//d[BL]-d[AL]<=DL->->->d[AL]+DL>=d[BL]
{
scanf("%d%d%d", &from, &to, &cost);//因为编号是有序的,所以只用储存单向边就可以了
edge[edge_sum].next = Head[from]; edge[edge_sum].to = to; edge[edge_sum].cost = cost;
Head[from] = edge_sum++;
}
for (i = ; i < MD; i++)//d[BL]-d[AL]>=DL->->->d[BD]-DD>=d[AD]
{
scanf("%d%d%d", &from, &to, &cost);
edge[edge_sum].next = Head[to]; edge[edge_sum].to = from; edge[edge_sum].cost = -cost;
Head[to] = edge_sum++;
}
for (i = ; i + <= cows_sum; i++)//d[i+1]+0>=d[i]
{
edge[edge_sum].next = Head[i + ]; edge[edge_sum].to = i; edge[edge_sum].cost = ;
Head[i + ] = edge_sum++;
}
SPFA(cows_sum, edge_sum);
}
return ;
} void SPFA(const int cows_sum, const int edge_sum)//这次用STL玩玩
{
Position out_pos, to;
queue<Position>que;
que.push(); dist[] = ; used[] = ; while (!que.empty())
{
out_pos = que.front(); que.pop();
used[out_pos] = ;//出队了就标记为0
out[out_pos]++;
if (out[out_pos] > cows_sum)
{
printf("-1\n");
return;
}
for (int k = Head[out_pos]; k != -; k = edge[k].next)
{
to = edge[k].to;
if (dist[to] > dist[out_pos] + edge[k].cost)
{
dist[to] = dist[out_pos] + edge[k].cost;
if (!used[to])
{
used[to] = ;
que.push(to);
}
}
}
}
if (dist[cows_sum] == MAX)
printf("-2\n");
else
printf("%d\n", dist[cows_sum]);
}
ShortestPath:Layout(POJ 3169)(差分约束的应用)的更多相关文章
- POJ - 3169 差分约束
题意:n头牛,按照编号从左到右排列,两头牛可能在一起,接着有一些关系表示第a头牛与第b头牛相隔最多与最少的距离,最后求出第一头牛与最后一头牛的最大距离是多少,如 果最大距离无限大则输出 ...
- POJ 3169 Layout (spfa+差分约束)
题目链接:http://poj.org/problem?id=3169 题目大意:n头牛,按编号1~n从左往右排列,可以多头牛站在同一个点,给出ml行条件,每行三个数a b c表示dis[b]-dis ...
- POJ 3169 Layout (图论-差分约束)
Layout Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6574 Accepted: 3177 Descriptio ...
- poj 3159(差分约束经典题)
题目链接:http://poj.org/problem?id=3159思路:题目意思很简单,都与给定的条件dist[b]-dist[a]<=c,求dist[n]-dist[1]的最大值,显然这是 ...
- [Usaco2005 dec]Layout 排队布局 差分约束
填坑- 差分约束一般是搞一个不等式组,求xn-x1的最大最小值什么的,求最大值就转化成xa<=xb+w这样的,然后建图跑最短路(这才是最终约束的),举个例子 x1<=x0+2x2<= ...
- poj 1201 差分约束
http://www.cnblogs.com/wangfang20/p/3196858.html 题意: 求集合Z中至少要包含多少个元素才能是每个区间[ai,bi]中的元素与Z中的元素重合个数为ci. ...
- BZOJ1731:[USACO]Layout 排队布局(差分约束)
Description Like everyone else, cows like to stand close to their friends when queuing for feed. FJ ...
- bzoj 1731: [Usaco2005 dec]Layout 排队布局 ——差分约束
Description 当排队等候喂食时,奶牛喜欢和它们的朋友站得靠近些.FJ有N(2<=N<=1000)头奶牛,编号从1到N,沿一条直线站着等候喂食.奶牛排在队伍中的顺序和它们的编号是相 ...
- bzoj 1731 [Usaco2005 dec]Layout 排队布局——差分约束
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1731 对差分约束理解更深.还发现美妙博客:http://www.cppblog.com/me ...
随机推荐
- SpringMVC配置
博客园 闪存 首页 新随笔 联系 管理 订阅 随笔- 4 文章- 1 评论- 0 搭建springmvc框架的另一种思路 在一个完整的项目里搭建springmvc框架的时候, 通常情况下,初学者 ...
- poj 3261 二分答案+后缀数组 求至少出现k次的最长重复子序列
#include "stdio.h" #define maxn 20010 int wa[maxn],wb[maxn],wv[maxn],ws[maxn]; int rank[ma ...
- TYVJP1933 绿豆蛙的归宿
背景 随着新版百度空间的上线,Blog宠物绿豆蛙完成了它的使命,去寻找它新的归宿. 描述 给出一个有向无环图,起点为1终点为N,每条边都有一个长度,并且从起点出发能够到达所有的点,所有的点也都能够到达 ...
- C/C++ 跨平台交叉编译、静态库/动态库编译、MinGW、Cygwin、CodeBlocks使用原理及链接参数选项
目录 . 引言 . 交叉编译 . Cygwin简介 . 静态库编译及使用 . 动态库编译及使用 . MinGW简介 . CodeBlocks简介 0. 引言 UNIX是一个注册商标,是要满足一大堆条件 ...
- TCP/IP详解 学习六
从ip层看路由表 选路策略 选路策略:决定把哪些路由放到路由表的规则. Ip执行选路机制,而路由守护程序则提供选路策略. Netstat –rn 打印路由表,如果没有-n命令会搜索配置文件,将网络地 ...
- myeclipse 引入jar包 (包括 jdbc 驱动引用)
A.直接用MyEclipse里自带的相关的项目jar包,右击项目"MyEclipse"菜单,选择对应的jar包就OK了 B.添加外部的jar包到web项目的lib包下,右击项目&q ...
- 【js】JSON.stringify 语法实例讲解
语法: JSON.stringify(value [, replacer] [, space]) value:是必选字段.就是你输入的对象,比如数组,类等. replacer:这个是可选的.它又分为 ...
- intent属性
private String mAction;private Uri mData;private String mType;private String mPackage;private Compon ...
- 操作haproxy配置文件教师版
作用: 可查,可增,可删,可修改 #_*_coding:utf-8_*_ import os def file_handle(filename,backend_data,record_list=Non ...
- 文件系统:drbd主备服务器文件同步
一. DRBD介绍 DRBD是一种块设备,可以被用于高可用(HA)之中.它类似于一个网络RAID-1功能.当你将数据写入本地 文件系统时,数据还将会被发送到网络中另一台主机上.以相同的形式记录在一个文 ...