• 小K的农场(luogu P1993


                                   题目传送门

    题目描述

    小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。

     

      差分约束求可行解。判负环的时候spfa用stack代替queue会快很多。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #include<stack>
     8 #include<bitset>
     9 #define LL long long
    10 #define RI register int
    11 using namespace std;
    12 const int INF = 0x7ffffff ;
    13 const int N = 10000 + 10 ;
    14 
    15 inline int read() {
    16     int k = 0 , f = 1 ; char c = getchar() ;
    17     for( ; !isdigit(c) ; c = getchar())
    18       if(c == '-') f = -1 ;
    19     for( ; isdigit(c) ; c = getchar())
    20       k = k*10 + c-'0' ;
    21     return k*f ;
    22 }
    23 struct Edge {
    24     int to, next, val ;
    25 }e[N<<1] ;
    26 int n, m ; int head[N], dis[N], num[N] ;
    27 inline void add_edge(int x,int y,int z) {
    28     static int cnt = 0 ;
    29     e[++cnt].to = y, e[cnt].next = head[x], head[x] = cnt, e[cnt].val = z ;
    30 }
    31 
    32 inline bool spfa() {
    33     memset(dis,127,sizeof(dis)) ; dis[0] = 0 ; 
    34     stack<int>s ; s.push(0) ; bitset<N>ins ; ins[0] = 1 ;
    35     while(!s.empty()) {
    36         int x = s.top() ; s.pop() ; num[x]++ ; if(num[x] > n) return 0 ;
    37         for(int i=head[x];i;i=e[i].next) {
    38             int y = e[i].to ; 
    39             if(dis[y] > dis[x]+e[i].val) {
    40                 dis[y] = dis[x]+e[i].val ;
    41                 if(!ins[y]) {
    42                     s.push(y) ; ins[y] = 1 ;
    43                 }
    44             }
    45         }
    46         ins[x] = 0 ;
    47     }
    48     return 1 ;
    49 }
    50 
    51 int main() {
    52     n = read(), m = read() ;
    53     while(m--) {
    54         int ii = read() ;
    55         if(ii == 1) {
    56             int x = read(), y = read(), z = read() ;
    57             add_edge(y,x,-z) ;
    58         } else if(ii == 2) {
    59             int x = read(), y = read(), z = read() ;
    60             add_edge(x,y,z) ;
    61         } else {
    62             int x = read(), y = read() ;
    63             add_edge(y,x,0), add_edge(x,y,0) ;
    64         }
    65     }
    66     for(int i=1;i<=n;i++) add_edge(0,i,0) ;
    67     if(spfa()) printf("Yes") ;
    68     else printf("No") ;
    69     return 0 ;
    70 }
  • 相关阅读:
    【转】HEIF图片存储格式探秘
    【转】Maven项目中将配置文件打包到jar包中
    C++ 单词接龙
    vector vector int 初始化
    哈夫曼树的特点
    哈夫曼树的构造
    单链表的逆转(测试数据)
    单链表的逆转
    二叉搜索树的插入
    二叉搜索数的应用
  • 原文地址:https://www.cnblogs.com/zub23333/p/8831191.html
Copyright © 2020-2023  润新知