• 洛谷 P1993 小K的农场 解题报告


    P1993 小K的农场

    题目描述

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

    说明

    对于 100% 的数据保证:1 ≤ n,m,a,b,c ≤ 10000。


    熟悉差分约束的话应该一眼就能看出来。

    对“至少”正向连负边,对“至多”负向连正边,判断有没有负环即可。

    不过这个题跑BFS_SPFA会TLE,得用DFS_SPFA,值得一题的是,两者判负环的方式并不一样。

    BFS_SPFA是判断一个点是否入队n次,而DFS_SPFA则判断一个点是否在一条链上出现多次。

    其实大部分情况来说,还是写BFS的比较稳,DFS的效率不太稳定。


    Code:(其实有个细节问题没判居然还过了)

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #define rg register
    using namespace std;
    const int N=10002;
    int n,m,dis[N],used[N];
    int head[N],edge[N<<1],next[N<<1],to[N<<1],cnt=0,in[N];
    void add(rg int u,rg int v,rg int w)
    {
        edge[++cnt]=w;next[cnt]=head[u];to[cnt]=v;head[u]=cnt;
    }
    int read()
    {
        rg int x=0;char c;
        while(c<'0'||c>'9') c=getchar();
        while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
        return x;
    }
    void dfs(int u)
    {
        used[u]=1;
        for(rg int i=head[u];i;i=next[i])
        {
            rg int v=to[i],w=edge[i];
            if(dis[v]>dis[u]+w)
            {
                if(used[v])
                {
                    printf("No
    ");
                    exit(0);
                }
                dis[v]=dis[u]+w;
                dfs(v);
            }
        }
        used[u]=0;
    }
    int main()
    {
        freopen("test_data.in","r",stdin);
        rg int u,v,w,typ;
        n=read();m=read();
        for(int i=1;i<=m;i++)
        {
            rg int typ=read();
            if(typ==1)
            {
                u=read(),v=read(),w=read();
                add(u,v,-w);
                in[v]++;
            }
            else if(typ==2)
            {
                u=read(),v=read(),w=read();
                add(v,u,w);
                in[u]++;
            }
            else
            {
                u=read(),v=read();
                add(u,v,0),add(v,u,0);
                in[u]++,in[v]++;
            }
        }
        for(rg int i=1;i<=n;i++)
            if(!in[i])
                add(0,i,0);
        memset(dis,0x3f,sizeof(dis));
        dis[0]=0;
        dfs(0);
        printf("Yes
    ");
        return 0;
    }
    
    

    2018.6.22

  • 相关阅读:
    谈谈SpringFramework与IoC依赖查找
    监控微博、论坛的“棱镜计划”
    输出质数的方法改进
    参数解构
    直接插入排序
    理解迭代
    异常处理
    函数
    continue语句
    break语句
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9214468.html
Copyright © 2020-2023  润新知