zoukankan      html  css  js  c++  java
  • bzoj3436 小K的农场

    3436: 小K的农场

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 853  Solved: 391
    [Submit][Status][Discuss]

    Description

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

    Input

    第一行包括两个整数n和m,分别表示农场数目和小K记忆中的信息的数目接下来m行:如果每行的第一个数是1,接
    下来有三个整数a,b,c,表示农场a比农场b至少多种植了c个单位的作物如果每行第一个数是2,接下来有三个整数a
    ,b,c,表示农场a比农场b至多多种植了c个单位的作物如果每行第一个数是3,接下来有两个整数a,b,表示农场a
    种植的数量与b一样。1<=n,m,a,b,c<=10000

    Output

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

    Sample Input

    3 3
    3 1 2
    1 1 3 1
    2 2 3 2

    Sample Output

    Yes
    样例解释
    三个农场种植的数量可以为(2,2,1)
    分析:显然,题目告诉我们的条件可以转化为不等式,例如条件1,可以转化成b - a ≤ -c ,那么条件2就可以转换成 a - b ≤ c,如果b-a<=k1,c-b<=k2,c-a<=k3,求出c-a的最大值,怎么求呢?可以画一个图:那么注意到c - a <= k1 + k2,而c-a又 <= k3,所有我们求出k3和k1+k2之间的最小值即可,然后观察图,可以发现从a到c恰好有这样两条路径,而对应的最小值则是最短路,那么我们从减数向被减数连边,做最短路即可,但是本题只需要我们输出能不能行,也就是说每两个点之间能不能存在最短路,当一个有向图中出现了负环则不能形成最短路,因为在这个负环中每走一次则路径的长度更短,那么我们只需要判断一下图中是否有负环即可,那么可以用spfa判断,平时写的spfa算法都是bfs形式的,这次最好用dfs形式的,容易判断.
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 100010;
    struct node
    {
        int to, w;
    };
    vector<node> e[maxn];
    int vis[maxn],n,m,d[maxn];
    bool flag;
    
    void add(int u, int v, int w)
    {
        node temp;
        temp.to = v;
        temp.w = w;
        e[u].push_back(temp);
    }
    
    void spfa(int x)
    {
        vis[x] = 1;
        for (int i = 0; i < e[x].size(); i++)
        {
            node v = e[x][i];
            if (d[v.to] > d[x] + v.w)   
            {
                if (vis[v.to])   //存在更短的路径又被访问过,说明存在负环
                {
                    flag = true;
                    return;
                }
                d[v.to] = d[x] + v.w;
                spfa(v.to);
            }
        }
        vis[x] = false;
        return;
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= m; i++)
        {
            int x,a,b,c;
            scanf("%d", &x);
            if (x == 1)
            {
                scanf("%d%d%d", &a, &b, &c);
                add(a, b, 0 - c);
            }
            if (x == 2)
            {
                scanf("%d%d%d", &a, &b, &c);
                add(b, a, c);
            }
            if (x == 3)
            {
                scanf("%d%d", &a, &b);
                add(a, b, 0);
                add(b, a, 0);
            }
        }
        flag = false;
        for (int i = 1; i <= n; i++)
        {
            d[i] = 0;
            spfa(i);
            if (flag)
                break;
        }
        if (flag)
            printf("No");
        else
            printf("Yes");
    
        return 0;
    }
  • 相关阅读:
    D. Constructing the Array
    B. Navigation System
    B. Dreamoon Likes Sequences
    A. Linova and Kingdom
    G. Special Permutation
    B. Xenia and Colorful Gems
    Firetrucks Are Red
    java getInstance()的使用
    java 静态代理和动态代理
    java 类加载机制和反射机制
  • 原文地址:https://www.cnblogs.com/zbtrs/p/5811358.html
Copyright © 2011-2022 走看看