zoukankan      html  css  js  c++  java
  • BZOJ 3436 小K的农场 差分约束

    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
     
     
    差分约束有一段时间没做了,又看了一遍,感觉比以前有了更好的认识。
    接下来是证明:
    然后,相等的情况,只需要连一条边,不然的话,相当于一个 0 的长度的环,又不能松弛,也不会死循环在里面,但是,在遍历邻接表的时候;
    每次都做了无用的比较。
      1 /**************************************************************
      2     Problem: 3436
      3     User: TreeDream
      4     Language: C++
      5     Result: Accepted
      6     Time:140 ms
      7     Memory:2220 kb
      8 ****************************************************************/
      9  
     10 #include <bits/stdc++.h>
     11  
     12 using namespace std;
     13  
     14 const int maxn = 10010;
     15  
     16 struct Edge
     17 {
     18     int from,to,dist;
     19 };
     20  
     21 inline int getint()
     22 {
     23     int w=0,q=0; char c=getchar();
     24     while((c<'0' || c>'9') && c!='-') c=getchar(); if(c=='-') q=1,c=getchar();
     25     while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); return q ? -w : w;
     26 }
     27  
     28 struct BellmanFord
     29 {
     30     int n,m;
     31     vector<Edge> edges;
     32     vector<int> G[maxn];
     33     bool inq[maxn];
     34     int d[maxn];
     35     int p[maxn];
     36     int cnt[maxn];
     37  
     38     void init(int n)
     39     {
     40         this->n = n;
     41         for(int i=0; i<n; i++) G[i].clear();
     42         edges.clear();
     43     }
     44  
     45     void AddEdge(int from,int to,int dist)
     46     {
     47         edges.push_back((Edge)
     48         {
     49             from,to,dist
     50         });
     51         m = edges.size();
     52         G[from].push_back(m-1);
     53     }
     54  
     55     bool negativeCycle()
     56     {
     57         queue<int> Q;
     58         memset(inq,0,sizeof(inq));
     59         memset(cnt,0,sizeof(cnt));
     60         for(int i=0; i<n; i++)
     61         {
     62             d[i] = 0;
     63             inq[0] = true;
     64             Q.push(i);
     65         }
     66  
     67         while(!Q.empty())
     68         {
     69             int u = Q.front();
     70             Q.pop();
     71             inq[u] = false;
     72             for(int i=0; i<G[u].size(); i++)
     73             {
     74                 Edge& e = edges[G[u][i]];
     75                 if(d[e.to]>d[u]+e.dist)
     76                 {
     77                     d[e.to] = d[u] + e.dist;
     78                     p[e.to] = G[u][i];
     79                     if(!inq[e.to]) {
     80                         Q.push(e.to);
     81                         inq[e.to] = true;
     82                         if(++cnt[e.to]>n)
     83                             return true;
     84                     }
     85                 }
     86             }
     87         }
     88         return false;
     89     }
     90  
     91 };
     92  
     93 BellmanFord sol;
     94  
     95 int main()
     96 {
     97     int n,m;
     98     n = getint();
     99     m = getint();
    100  
    101     sol.init(n+1);
    102     int a,b,c;
    103     int flag;
    104     while(m--)
    105     {
    106         flag = getint();
    107         //scanf("%d",&flag);
    108         if(flag==2)
    109         {
    110             a = getint();
    111             b = getint();
    112             c = getint();
    113             //scanf("%d%d%d",&a,&b,&c);
    114             sol.AddEdge(b,a,c);
    115         }
    116         else if(flag==1)
    117         {
    118             a = getint();
    119             b = getint();
    120             c = getint();
    121             //scanf("%d%d%d",&a,&b,&c);
    122             sol.AddEdge(a,b,-c);
    123         }
    124         else if(flag==3)
    125         {
    126             a = getint();
    127             b = getint();
    128             //scanf("%d%d",&a,&b);
    129             sol.AddEdge(a,b,0);
    130             //sol.AddEdge(b,a,0);
    131         }
    132     }
    133     for(int i=0; i<n; i++)
    134         sol.AddEdge(0,i,0);
    135  
    136     if(sol.negativeCycle())
    137     {
    138         puts("No");
    139     }
    140     else puts("Yes");
    141  
    142     return 0;
    143 }
    View Code
     
     
  • 相关阅读:
    day14
    day13
    装饰器小题
    day12
    tes..
    1380 没有上司的舞会
    算法模板——KMP字符串匹配
    算法模板——Tarjan强连通分量
    3211: 花神游历各国
    1131: [POI2008]Sta
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6576816.html
Copyright © 2011-2022 走看看