ssoj1750小K 的农场(差分约束系统)

题目描述

小K 是个特么喜欢玩MC 的孩纸。。。
    小K 在MC 里面建立很多很多的农场,总共n 个,以至于他自己都忘记了每个农场中种植作物的具体数量了,他只记得一些含糊的信息(共m 个),以下列三种形式描述:
    农场a 比农场b 至少多种植了c 个单位的作物,农场a 比农场b 至多多种植了c 个单位的作物,农场a 与农场b 种植的作物数一样多。但是,由于小K 的记忆有些偏差,所以他想要知道存不存在一种情况,使得农场的种植作物数量与他记忆中的所有信息吻合。

输入

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

接下来m 行:

如果每行的第一个数是1,接下来有三个整数a,b,c,表示农场a 比农场b 至少多种植了c 个单位的作物

如果每行第一个数是2,接下来有三个整数a,b,c,表示农场a 比农场b 至多多种植了c 个单位的作物

如果每行第一个数是3,接下来有两个整数a,b,表示农场a 种植的数量与b一样多

输出

如果存在某种情况与小K 的记忆吻合,输出“Yes” ,否则输出“No”

样例输入

3 33 1 21 1 3 12 2 3 2

样例输出

Yes

提示

【样例解释】三个农场种植的数量可以为(2,2,1)。

【数据范围与约定】

对于10%的数据,1 <= n ,m<= 10

对于100%的数据,1 <= n,m,a,b,c <= 10000


#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=100005;
const int inf=1000000009;
struct data{
    int v,w,nxt;
}e[maxn*2];
int n,m,cnt=0;
int dis[maxn],tim[maxn],fst[maxn];
bool vis[maxn],f=1;
inline int get(){
    char c;while(!isdigit(c=getchar()));
    int v=c-48;while(isdigit(c=getchar()))v=v*10+c-48;
    return v;
}
inline void add(int x,int y,int z){
    e[++cnt].v=y,e[cnt].w=z,e[cnt].nxt=fst[x],fst[x]=cnt;
}
queue<int>q;
inline void spfa(){
    dis[n+1]=0;
    vis[n+1]=1;
    q.push(n+1);
    while(!q.empty()){
        int x=q.front();q.pop();vis[x]=0;
        for(int i=fst[x];i;i=e[i].nxt){
            int y=e[i].v;++tim[y];
            if(tim[y]>101){f=0;break;}
            if(dis[y]>dis[x]+e[i].w){
                dis[y]=dis[x]+e[i].w;
                if(!vis[y])q.push(y),vis[y]=1;
            }
        }
        if(!f)break;
    }
}
int main(){
    n=get();m=get();
    memset(vis,0,sizeof(vis));
    memset(tim,0,sizeof(tim));
    for(int i=1;i<=m;++i){
        int p=get();
        int x,y,z;
        if(p==1)x=get(),y=get(),z=get(),add(x,y,-z);
        if(p==2)x=get(),y=get(),z=get(),add(y,x,z);
        if(p==3)x=get(),y=get(),add(x,y,0),add(y,x,0);
    }
    for(int i=1;i<=n;++i)add(n+1,i,0),dis[i]=inf;
    spfa();
    if(f)printf("Yes\n");
    else printf("No\n");
    return 0;
}

思路:典型的差分约束系统。易知有负环时方案不存在.

注意:(1)由于0边和源点多连了边,所以maxn要开大一点。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值