当前位置:网站首页>(Part of it is not understood, and the notes are not completed) [Graph Theory] Difference Constraints
(Part of it is not understood, and the notes are not completed) [Graph Theory] Difference Constraints
2022-08-02 07:26:00 【gzkeylucky】
知识点
一. 前置知识:判断负环
二.差分约束
差分约束系统即为n元一次不等式组,each constraint都是由两个变量作差构成的,形如
,The goal is to find a set of solutions that satisfy all constraints.
可变形为
,与Triangular Inequality in Shortest Path
相似,So consider the variables in the inequality group as points,each constraint
为从节点 j 向节点 i 连一条边权为
的有向边,After running the most short circuit,
is a set of solutions in a differentially constrained system,若When there exists negative ring and destination unreachable,无解.
变形为
;
变形为
;
变形为
;
变形为
且
;
必要时,建一个超级源点.
那么,When do you need to create a super origin??
有的时候,In order to ensure the connectivity of the entire range,Just need to build a super source point makes the whole graph is connected.但是需要注意的是,During normal construction,If it is from big to small,At this time, we should also follow this principle when creating a super source point,If it is from small to large,When creating a super source point, it can be reversed.
!Find the maximum solution using the shortest path,Find the smallest solution using the longest path
题目描述
给出一组包含 m 个不等式,有 n 个未知数的形如:

的不等式组,求任意一组满足这个不等式组的解.
输入格式
第一行为两个正整数 n,m,代表未知数的数量和不等式的数量.
接下来 m 行,每行包含三个整数 c,c′,y,On behalf of an inequality
.
输出格式
一行,n 个数,表示
的一组可行解,如果有多组解,Please output any group,无解请输出 NO.
输入输出样例
输入 #1
3 3 1 2 3 2 3 -2 1 3 1
输出 #1
5 3 5
说明/提示
样例解释

一种可行的方法是
.

数据范围
对于 100% 的数据,
,
,
,
.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;
int n,m;
const int maxn=1e7+5,INF=0x3f3f3f3f;
struct node{
int to,next,w;
}edge[maxn<<1];
int head[maxn],num=0,dis[maxn],ans[maxn];
bool vis[maxn];
queue <int> q;
inline int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
x=(x<<3)+(x<<1)+(c^48);
c=getchar();
}
return x*f;
}
inline void write(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline void add(int u,int v,int w)
{
edge[++num].to=v;
edge[num].w=w;
edge[num].next=head[u];
head[u]=num;
}
inline bool spfa()
{
memset(dis,INF,sizeof(dis));
memset(ans,0,sizeof(ans));
memset(vis,0,sizeof(vis));
q.push(0); //from super origin
vis[0]=1;
dis[0]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(dis[v]>dis[u]+edge[i].w)
{
dis[v]=dis[u]+edge[i].w;
ans[v]=ans[u]+1;
if(ans[v] >= n+1)
{
return 1;
}
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
return 0;
}
int main()
{
n=read(); m=read();
memset(head,-1,sizeof(head));
for(int i=1;i<=m;++i)
{
int a=read(),b=read(),y=read();
add(b,a,y); //要注意从b到a,Minus in front
}
for(int i=1;i<=n;++i)
{
add(0,i,0); //Construct the super origin
}
if(spfa() == 1) printf("NO\n");
else
{
for(int i=1;i<=n;++i)
{
write(dis[i]);
putchar(' ');
}
}
return 0;
}相关练习
思路:According to the topic of“至多”,“至少”和“一样多”,The following three equations can be obtained:

Usually when solving problems,We want to be able to convert the problem into a model,Or use a general formula to solve a large number of problems.
Then in the above three equations,①式和②are inequalities,can be viewed as a directed edge of the graph.We want to convert both expressions into the same expression.那么将②multiply both sides by-1,Convert the formula to
,与①式相似.
但是,③Equation,Then it can be regarded as an undirected edge of the graph,除了③式,还可以表示为
,在代码实现的时候,build twice as if building an undirected edge.
In order to ensure the connectivity of the graph,We need to build a super origin that guarantees connectivity,Then start from this super origin and run the shortest path,最后,Be careful to judge the negative ring!
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;
int n,m;
const int maxn=1e7+5,INF=0x3f3f3f3f;
struct node{
int to,next,w;
}edge[maxn<<1];
int head[maxn],num=0,dis[maxn],ans[maxn];
bool vis[maxn];
queue <int> q;
inline int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
x=(x<<3)+(x<<1)+(c^48);
c=getchar();
}
return x*f;
}
inline void add(int u,int v,int w)
{
edge[++num].to=v;
edge[num].w=w;
edge[num].next=head[u];
head[u]=num;
}
inline bool spfa()
{
memset(dis,INF,sizeof(dis));
memset(ans,0,sizeof(ans));
memset(vis,0,sizeof(vis));
q.push(0);
vis[0]=1;
dis[0]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(dis[v]>dis[u]+edge[i].w)
{
dis[v]=dis[u]+edge[i].w;
ans[v]=ans[u]+1;
if(!vis[v])
{
q.push(v);
vis[v]=1;
}
if(ans[v]==n)
{
return 0;
}
}
}
}
return 1;
}
int main()
{
n=read(); m=read();
memset(head,-1,sizeof(head));
for(int i=1;i<=n;++i)
{
add(0,i,0);
}
for(int i=1;i<=m;++i)
{
int num=read();
int a,b,c;
if(num == 1) //a-b<=c的情况
{
a=read(),b=read(),c=read();
add(a,b,-c);
}
else if(num == 2) //a-b >= c的情况
{
a=read(),b=read(),c=read();
add(b,a,c);
}
else
{
a=read(),b=read();
add(a,b,0);
add(b,a,0);
}
}
if(spfa()== 1) printf("Yes");
else printf("No");
return 0;
}2. 洛谷 P1250 种树
方法一:贪心算法
思路:This problem is well understood by greedy algorithm.In order to ensure the minimum number of trees planted,Then the more trees that need to be planted in the overlapping part of the interval,However, the overlapping part must be at the end of the interval,So first sort the nodes at the end of the interval,Then first plant trees at the head of the interval from front to back until the requirements are met,对于下一个区间,See how many trees are missing,how much at the end.
步骤如下:
1. Sort by end position
2. process each interval:Scan the interval from front to back,Count the number of existing trees
If the number of selected points exceeds the required number,则continue;Or from the back forward,Add the missing points
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;
int n,h,ans=0;
const int maxn=1e7+5;
bool vis[maxn];
struct node{
int b,e,t;
}edge[maxn<<1];
inline int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0' && c<='9')
{
x=(x<<3)+(x<<1)+(c^48);
c=getchar();
}
return x*f;
}
inline bool cmp(node x,node y) //According to the end node
{
return x.e<y.e;
}
int main()
{
n=read(); h=read();
for(int i=1;i<=h;++i)
{
edge[i].b=read();
edge[i].e=read();
edge[i].t=read();
}
sort(edge+1,edge+h+1,cmp);
memset(vis,0,sizeof(vis));
for(int i=1;i<=h;++i)
{
int sum=0;
for(int j=edge[i].b;j<=edge[i].e;++j) //Once upon a time in the future search range
{
if(vis[j]!=0) //There are marked points in the interval
{
sum++;
}
}
if(sum >= edge[i].t) continue;
for(int j=edge[i].e;j>=edge[i].b;--j) //从后往前搜索
{
if(vis[j] == 0) //Add the tree to be planted in the overlapping part
{
vis[j]=1;
sum++; //The number of statistical intervals increases
ans++; //总数增加
if(sum == edge[i].t) break;
}
}
}
printf("%d",ans);
return 0;
}方法二:差分约束
思路:
根据题意:对于each constraint
,最小值为w ,The length of the interval can be expressed as
,Convert the difference between two numbers to
,即
,表示在区间
之间至少有w棵树(sum[x]为x的前缀和).And because in each interval can only choose different species or species1棵树,get the implicit condition:
.
Another point to note in this question is that:The established super origin isn+1.根据题意,序号为1The location is where trees can be planted,如果从0Start building a super origin,may result in serial number1The location can only be maintained without tree planting.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;
int n,h;
const int maxn=1e7+5,INF=0x3f3f3f3f;
struct node
{
int to,next,w;
}edge[maxn<<1];
int head[maxn],num=0,dis[maxn];
struct node1
{
int b,e,t;
}edge1[maxn<<1];
bool vis[maxn];
queue <int> q;
inline int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
x=(x<<3)+(x<<1)+(c^48);
c=getchar();
}
return x*f;
}
inline void write(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline void add(int u,int v,int w)
{
edge[++num].to=v;
edge[num].w=w;
edge[num].next=head[u];
head[u]=num;
}
inline bool spfa()
{
memset(dis,INF,sizeof(dis));
q.push(n+1); //Starting from the origin of the super lookup
vis[n+1]=1;
dis[n+1]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(dis[v]>dis[u]+edge[i].w)
{
dis[v]=dis[u]+edge[i].w;
if(!vis[v])
{
q.push(v);
vis[v]=1;
}
}
}
}
return 0;
}
int main()
{
n=read(); h=read();
memset(head,-1,sizeof(head));
for(int i=0;i<=n;++i)
{
add(n+1,i,0); //The super origin here isn+1
}
for(int i=1;i<=h;++i)
{
edge1[i].b=read();
edge1[i].e=read();
edge1[i].t=read();
add(edge1[i].e,edge1[i].b-1,-edge1[i].t); //Edge construction
}
for(int i=1;i<=n;++i)
{
add(i,i-1,0);
add(i-1,i,1);
}
spfa();
write(-dis[0]); //When input is a negative side,output to be negated;
return 0;
}边栏推荐
- Mining game (C language)
- Nodejs installation tutorial
- MySQL高级-MVCC(超详细整理)
- request.getSession(), the story
- MySQL(3)
- MySQL经典50道练习题及全网最详细解析
- .NET静态代码织入——肉夹馍(Rougamo) 发布1.1.0
- MySql -- 不存在则插入,存在则更新或忽略
- request.getSession(),的故事
- July 18-July 31, 2022 (Ue4 video tutorials and documentation, 20 hours. Total 1412 hours, 8588 hours left)
猜你喜欢

MySQL high-level --- storage engine, index, lock

MySQL高级-MVCC(超详细整理)

How the Internet of Things is changing the efficiency of city operations

MySQL驱动jar包的下载--保姆教程

Node installation and configuration (node-v12.20.2-x64 ) and introduction to node version switching

zabbix email alarm and WeChat alarm

yml字符串读取时转成数字了怎么解决

文件上传漏洞(二)

Vscode连接远程服务器出现‘Acquiring lock on/home/~’问题

Revitalize rural circular economy and digital chain to link agricultural "ecological chain"
随机推荐
【npm install 报错问题合集】- npm ERR! code ENOTEMPTY npm ERR! syscall rmdir
Connection reset by peer 问题解析
DNS resolution process
Two good php debug tutorials
Understand C operators in one article
MySQL 5.7 安装教程(全步骤、保姆级教程)
HCIP 第二天
typescript ‘props‘ is declared but its value is never read 解决办法
8/1 思维+扩展欧几里得+树上dp
punch day05
Toolbox App 1.25 New Features at a Glance | Version Update
MySQL 5.7 installation tutorial (full-step, nanny-level tutorial)
PHP Warning: putenv() has been disabled for security reasons in phar
MySQL驱动jar包的下载--保姆教程
mysql索引失效的常见9种原因详解
npm ---- install yarn
.NET Static Code Weaving - Rougamo Release 1.1.0
[npm install error report collection] - npm ERR! code ENOTEMPTY npm ERR! syscall rmdir
HCIP 第三天实验
Xgboost报错 ValueError: Invalid shape: (1650, 2) for label