Poj 3169(差分约束系统)

简介: Poj 3169(差分约束系统)

题目传送门

首先我们要知道最短路问题的本质是:

1 11.从起点S出发到各个顶点v的最短距离是d [ v ] d[v]d[v]

2. 对 于 每 条 权 值 为 w 的 边 e = ( v , u ) , 都 有 d [ v ] + w > = d [ u ] 成 立 2.对于每条权值为w的边e=(v,u),都有d[v]+w>=d[u]成立2.we=(v,u),d[v]+w>=d[u]

3. 3.3.当所有满足以上的所有不等式的d中,d [ v ] − d [ s ] d[v]-d[s]d[v]d[s]的最大值就是从S到V的最短距离(注意是最大值才是最短距离)

所有这些不等式两边都只出现一个变量,所以这种特殊不等式方程组叫做差分约束系统

最短路就是一种差分约束系统

本题中:1.首先每个点已经按序号排成一排分配好了: d [ i + 1 ] + 0 > = d [ i ] d[i+1]+0>=d[i]d[i+1]+0>=d[i],可以连一条i + 1 i+1i+1指向i ii的权值为0的边,也可以不连,因为权值为0是不会进行松弛操作的

2. d [ A L ] + D L > = d [ B L ] 2.d[AL]+DL>=d[BL]2.d[AL]+DL>=d[BL],可以连一条由AL指向BL的权值为DL的边

3. d [ A D ] + D D < = d [ B D ] , 变 形 为 d [ B D ] − D D > = d [ A D ] 3.d[AD]+DD<=d[BD],变形为d[BD]-DD>=d[AD]3.d[AD]+DD<=d[BD],d[BD]DD>=d[AD],可以连一条由,BD指向AD的权值为-DD的边(负边)

此时处理出来的不等式约束条件完美符合差分约束系统,所以直接用spfa或者bellman_ford算法来求解

注意:判断无法满足约束条件,则从1到n的路上有负环(只要1到n没有负环就行了,其他地方有没有不重要

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
const int N = 1e4 + 10, INF = 0x3f3f3f3f;
struct edge
{
  int to;
  int cost;
};
int n, ml, md;
vector<edge>g[N];
int d[N];//最小距离
bool st[N];
int cnt[N];//当1-v的路上边的个数cnt[v]>=n,则路上有大于等于n+1个点,但是一共只有n个点所以,此时必有负环
int spfa()
{
  memset(d, 0x3f, sizeof(d));
  st[1] = 1;
  queue<int>q;
  q.push(1);
  d[1] = 0;
  while (q.size())
  {
    int t = q.front();
    q.pop();
    st[t] = 0;
    for (int i = 0; i < g[t].size(); i++)
    {
      edge x = g[t][i];
      if (d[x.to] > d[t] + x.cost)
      {
        d[x.to] = d[t] + x.cost;
        cnt[x.to] = cnt[t] + 1;//更新边的个数
        if (cnt[x.to] >= n) return -1;
        if (!st[x.to])
        {
          st[x.to] = 1;
          q.push(x.to);
        }
      }
    }
  }
  return d[n];
}
int  main()
{
  scanf("%d%d%d", &n, &ml, &md);
  for (int i = 1; i <= ml; i++)
  {
    int x, y, z;
    scanf("%d%d%d", &x, &y, &z);
    g[x].push_back({y, z});
  }
  for (int i = 1; i <= md; i++)
  {
    int x, y, z;
    scanf("%d%d%d", &x, &y, &z);
    g[y].push_back({x, -z});
  }
  int t = spfa();
  if (t == -1) cout << -1 << "\n";
  else if (t == INF)
  {
    cout << -2 << "\n";
  } else
  {
    cout << t << "\n";
  }
  return 0;
}

求最小值,dv>=du+w,从u向v连w的边或者反方向连负边,求最长路。
求最大值,dv<=du+w,从v向u连w的边,求最短路。
注意从超级源点出发。

目录
相关文章
|
数据可视化 定位技术 Sentinel
如何用Google Earth Engine快速、大量下载遥感影像数据?
【2月更文挑战第9天】本文介绍在谷歌地球引擎(Google Earth Engine,GEE)中,批量下载指定时间范围、空间范围的遥感影像数据(包括Landsat、Sentinel等)的方法~
5196 1
如何用Google Earth Engine快速、大量下载遥感影像数据?
|
算法 程序员
常见代码复杂度解析
代码质量评价维度,很多都是些主观性的评价维度,需要有专门的人员去查看评判代码,对于审核的人员代码能力要求比较高,而且有时候往往不同的人审核会得出不同的结论,会有争议。然而也有些对代码客观的分析方式可以帮助我们识别代码质量,节省大量人力去分析代码。比如代码复杂度的分析。
4214 0
|
1天前
|
存储 JavaScript 前端开发
JavaScript基础
本节讲解JavaScript基础核心知识:涵盖值类型与引用类型区别、typeof检测类型及局限性、===与==差异及应用场景、内置函数与对象、原型链五规则、属性查找机制、instanceof原理,以及this指向和箭头函数中this的绑定时机。重点突出类型判断、原型继承与this机制,助力深入理解JS面向对象机制。(238字)
|
2天前
|
安全 数据可视化 网络安全
安全无小事|阿里云先知众测,为企业筑牢防线
专为企业打造的漏洞信息收集平台
1302 2
|
3天前
|
云安全 人工智能
2025,阿里云安全的“年度报告”
拥抱AI时代,阿里云安全为你护航~
1447 2
|
10天前
|
机器学习/深度学习 安全 API
MAI-UI 开源:通用 GUI 智能体基座登顶 SOTA!
MAI-UI是通义实验室推出的全尺寸GUI智能体基座模型,原生集成用户交互、MCP工具调用与端云协同能力。支持跨App操作、模糊语义理解与主动提问澄清,通过大规模在线强化学习实现复杂任务自动化,在出行、办公等高频场景中表现卓越,已登顶ScreenSpot-Pro、MobileWorld等多项SOTA评测。
1417 7
|
11天前
|
人工智能 Rust 运维
这个神器让你白嫖ClaudeOpus 4.5,Gemini 3!还能接Claude Code等任意平台
加我进AI讨论学习群,公众号右下角“联系方式”文末有老金的 开源知识库地址·全免费
1300 16
|
5天前
|
人工智能 前端开发 API
Google发布50页AI Agent白皮书,老金帮你提炼10个核心要点
老金分享Google最新AI Agent指南:让AI从“动嘴”到“动手”。Agent=大脑(模型)+手(工具)+协调系统,可自主完成任务。通过ReAct模式、多Agent协作与RAG等技术,实现真正自动化。入门推荐LangChain,文末附开源知识库链接。
508 119
|
1天前
|
人工智能 自然语言处理 API
n8n:流程自动化、智能化利器
流程自动化助你在重复的业务流程中节省时间,可通过自然语言直接创建工作流啦。
305 3
n8n:流程自动化、智能化利器

热门文章

最新文章