zoukankan      html  css  js  c++  java
  • 2014.7.7 模拟赛【小K的农场】

    3.小K的农场(farm.pas/cpp/c)

    【题目描述】

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

    【输入格式】 farm.in

         第一行包括两个整数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一样多。

    【输出格式】 farm.out

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

    【样例输入】

    3 3

    3 1 2

    1 1 3 1

    2 2 3 2

    【样例输出】

    Yes

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

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

    查分约束……

    1代表a-b>=c,即b-a<=-c

    2代表a-b<=c

    3是a=b即a-b<=0且b-a<=0

    然后就是建图了

    1、2插单向边,3插双向边

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define S 0
    using namespace std;
    inline int read()  
    {  
        int x=0,f=1;char ch=getchar();  
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}  
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}  
        return x*f;  
    }
    struct edge{
    	int to,next,v;
    }e[200001];
    int cnt;
    int head[200001];
    inline void ins(int u,int v,int w)
    {
    	e[++cnt].v=w;
    	e[cnt].to=v;
    	e[cnt].next=head[u];
    	head[u]=cnt;
    }
    inline void insert(int u,int v,int w)
    {
    	ins(u,v,w);
    	ins(v,u,-w);
    }
    int n,m,ans;
    bool flag[50001];
    int dist[50001];
    inline void spfa(int x)
    {
    	flag[x]=1;
    	for (int i=head[x];i;i=e[i].next)
    	  {
    	  	if (dist[x]+e[i].v<dist[e[i].to])
    	  	{
    	  		if (flag[e[i].to]) {ans=1;return;}
    	  		dist[e[i].to]=dist[x]+e[i].v;
    	  		spfa(e[i].to);
    	  	}
    	  }
    	flag[x]=0;
    }
    int main()
    {
    	freopen("farm.in","r",stdin);
    	freopen("farm.out","w",stdout);
    	memset(dist,127/3,sizeof(dist));
    	n=read();m=read();
    	int opr,x,y,z;
    	for (int i=1;i<=n;i++)
    	  ins(S,i,0);
    	for (int i=1;i<=m;i++)
    	  {
    	  	opr=read();
    	  	x=read();
    	  	y=read();
    	  	if (opr!=3) z=read();
    	  	if (opr==1) ins(y,x,-z);
    	  	if (opr==2) ins(x,y,z);
    	  	if (opr==3) insert(x,y,0);
    	  }
    	dist[S]=0;
    	spfa(S);
    	if (ans) printf("No");
    	else printf("Yes");
    }


    ——by zhber,转载请注明来源
  • 相关阅读:
    百度--买帽子
    网易--双核处理器
    京东--通过考试
    简单错误记录
    链表中的倒数第k个结点
    数值的整数次方
    二进制中1的个数
    TCP 三次握手
    旋转数组的最小数字
    用两个栈实现队列
  • 原文地址:https://www.cnblogs.com/zhber/p/4036071.html
Copyright © 2011-2022 走看看