P1993 小K的农场
Posted garen-wang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1993 小K的农场相关的知识,希望对你有一定的参考价值。
第一道差分约束的题目,感觉有点懵。
差分约束有一点类似于拓扑排序建图的思想。
先给出解题套路:
形如(a geq b + c)的满足一种最长路的性质,所以可以使用最长路解决,可以解决求最小的问题。
形如(a leq b + c)的满足最短路的性质,使用最短路算法可以解决,可以解决求最大的问题。
但是你需要建立一个超级源点!我目前还不会。
回到题目。
农场a比农场b至少多种植了c个单位的作物,
体现为(a geq b + c)。移项得到(b - a leq -c)。
农场a比农场b至多多种植了c个单位的作物,
体现为(a leq b + c)。
农场a与农场b种植的作物数一样多。
体现为(a geq b) 且 (a leq b)。对前面的式子移项得到(b leq a)。
但是你显然不能一起做最长路和最短路吧,所以需要统一。
这里把所有东西都化为小于等于,已经在上面化好了。
这道题是存在性问题。如何解决存在性问题?
判负环!
因为这道题换成小于等于的话就要跑最短路,而存在负环就没最短路,有最短路当然就有答案。
所以又好好地复习了dfs型spfa。。。
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
const int maxn = 10005;
struct Edges
{
int next, to, weight;
} e[maxn << 2];
int head[maxn], tot;
int n, m;
bool vis[maxn];
int dist[maxn];
int read()
{
int ans = 0; char ch = getchar();
while(ch < ‘0‘ || ch > ‘9‘) ch = getchar();
while(ch >= ‘0‘ && ch <= ‘9‘)
{
ans = ans * 10 + ch - ‘0‘;
ch = getchar();
}
return ans;
}
void link(int u, int v, int w)
{
e[++tot] = (Edges){head[u], v, w};
head[u] = tot;
}
void dfs(int u)
{
vis[u] = true;
for(int i = head[u]; i; i = e[i].next)
{
int v = e[i].to;
if(dist[u] + e[i].weight < dist[v])
{
dist[v] = dist[u] + e[i].weight;
if(vis[v])
{
printf("No
");
exit(0);
}
else dfs(v);
}
}
vis[u] = false;
}
int main()
{
memset(dist, 0x3f, sizeof(dist));
n = read(), m = read();
while(m--)
{
int opt = read(), x = read(), y = read(), z;
if(opt == 3) link(x, y, 0), link(y, x, 0);
else
{
z = read();
if(opt == 1) link(x, y, -z);
else if(opt == 2) link(y, x, z);
}
}
for(int i = 1; i <= n; i++) if(!vis[i]) dfs(i);
printf("Yes
");
return 0;
}
/*
b - a <= - c first situation
a - b <= c second situation
a - b <= 0 && b - a<= 0 third situation
*/
以上是关于P1993 小K的农场的主要内容,如果未能解决你的问题,请参考以下文章