算法随笔——图论之差分约束
求不等式组的最大解和最小解:
神奇结论:求最大解跑最短路,求最小解跑最长路
设超级源点为
则跑最短路时,答案为
跑最长路时,答案为
感性理解一下还挺对的。
例题:[ABC216G] 01Sequence
一些相关的最短路基础知识:
spfa时间复杂度 O(nm)
dijstra 不能求解负权图,也不能求最长路。
而 spfa可以。
spfa 可以求负环,当一个点被松弛超过n次,则该图存在负环。
模板代码:
点击查看代码
// Problem: P3385 【模板】负环
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3385
// Memory Limit: 250 MB
// Time Limit: 2000 ms
// Author: Eason
// Date:2024-06-20 23:38:48
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
#define re register
#define PII pair<int,int>
int read()
{
int f=1,k=0;char c = getchar();
while(c <'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')k=(k<<1)+(k<<3)+(c^48),c=getchar();
return k*f;
}
const int N = 3e3+5;
int t,n,m;
vector<PII> v[N];
int dis[N],vis[N];
int cnt[N];
bool spfa()
{
memset(dis,INF,sizeof dis);
memset(vis,0,sizeof vis);
memset(cnt,0,sizeof cnt);
queue<int> q;
q.push(1);vis[1] = 1,dis[1] = 0;
while (q.size())
{
int u = q.front();q.pop();vis[u] = 0;
for (auto &[j,c] : v[u])
{
if (dis[j] > dis[u] + c)
{
dis[j] = dis[u] + c;
if (!vis[j]) vis[j] = 1,q.push(j);
if (++cnt[j] > n) return 0;
}
}
}
return 1;
}
void add(int a,int b,int c)
{
v[a].push_back({b,c});
}
int main()
{
cin >> t ;
while (t--)
{
cin >> n >> m;
for (int i = 1;i <= m;i++)
{
int x = read(),y = read(),w = read();
if (w >= 0) add(x,y,w),add(y,x,w);
else add(x,y,w);
}
if (spfa()) puts("NO");
else puts("YES");
for (int i = 1;i <= n;i++) v[i].clear();
}
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· DeepSeek本地性能调优
· 一文掌握DeepSeek本地部署+Page Assist浏览器插件+C#接口调用+局域网访问!全攻略