P1993 小K的农场 差分约束系统

这个题是一道差分约束系统的裸题,什么是差分约束系统呢?就是给了一些大小条件,然后让你找一个满足的图。这时就要用差分约束了。

怎么做呢?其实很简单,就是直接建图就好,但是要把所有条件变为小于等于号,假如是大于等于就要移项,小于要减一。然后根据这个建图。

相等怎么办?好办,就直接连就行了,长度随意,反正只是判连通。然后跑dfs(或者叫spfa)找负环(最长路),假如有负环就一定不成立。

题目描述

小K在MC里面建立很多很多的农场,总共n个,以至于他自己都忘记了每个农场中种植作物的具体数量了,他只记得一些含糊的信息(共m个),以下列三种形式描述:

    农场a比农场b至少多种植了c个单位的作物,
    农场a比农场b至多多种植了c个单位的作物,
    农场a与农场b种植的作物数一样多。

但是,由于小K的记忆有些偏差,所以他想要知道存不存在一种情况,使得农场的种植作物数量与他记忆中的所有信息吻合。
输入输出格式
输入格式:

第一行包括两个整数 n 和 m,分别表示农场数目和小 K 记忆中的信息数目。

接下来 m 行:

如果每行的第一个数是 1,接下来有 3 个整数 a,b,c,表示农场 a 比农场 b 至少多种植了 c 个单位的作物。
如果每行的第一个数是 2,接下来有 3 个整数 a,b,c,表示农场 a 比农场 b 至多多种植了 c 个单位的作物。如果每行的第一个数是 3,接下来有 2 个整数 a,b,表示农场 a 种植的的数量和 b 一样多。
输出格式:
如果存在某种情况与小 K 的记忆吻合,输出“Yes”,否则输出“No”。
输入输出样例
输入样例#1: 复制
3 3
3 1 2
1 1 3 1
2 2 3 2
输出样例#1: 复制
Yes
说明
对于 100% 的数据保证:1 ≤ n,m,a,b,c ≤ 10000

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(int i = a;i <= n;i++)
#define lv(i,a,n) for(int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
const int INF = 1 << 30;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
        if(c == '-') op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
        x = x * 10 + c - '0';
    if(op) x = -x;
}
template <class T>
void write(T x)
{
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar('0' + x % 10);
}
struct node
{
    int l,r,nxt,w;
}a[25000];
int n,m,len,lst[25000];
void add(int x,int y,int w)
{
    a[++len].l = x;
    a[len].r = y;
    a[len].nxt = lst[x];
    a[len].w = w;
    lst[x] = len;
}
int dis[25000],vis[25000];
bool spfa(int x)
{
    vis[x] = 1;
    for(int k = lst[x];k;k = a[k].nxt)
    {
        int y = a[k].r;
        if(dis[y] < dis[x] + a[k].w)
        {
            dis[y] = dis[x] + a[k].w;
            if(vis[y] == 1)
            return 0;
            if(spfa(y) == 0)
            return 0;
        }
    }
    vis[x] = 0;
    return 1;
}
int main()
{
    int f,a,b,c;
    read(n);read(m);
    duke(i,1,m)
    {
        read(f);
        if(f == 1)
        {
            read(a);read(b);read(c);
            add(b,a,c);
        }
        else if(f == 2)
        {
            read(a);read(b);read(c);
            add(a,b,-c);
        }
        else
        {
            read(a);read(b);
            add(a,b,0);
            add(b,a,0);
        }
    }
    duke(i,1,n)
    {
        add(0,i,0);
        dis[i] = -INF;
    }
    if(spfa(0) == 1)
    printf("Yes");
    else
    printf("No");
    return 0;
}

 

posted @ 2018-09-22 21:11  DukeLv  阅读(173)  评论(0编辑  收藏  举报