BZOJ3436 小K的农场
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ3436 小K的农场相关的知识,希望对你有一定的参考价值。
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3436
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一样多
Output
如果存在某种情况与小K的记忆吻合,输出”Yes”,否则输出”No”
写了个常规SPFA,整整跑了6704ms
教主说Greens在出题的时候是要卡常规SPFA TLE的,要用SLF或者DFS版SPFA
DFS版SPFA?翻了教主的代码,除了把queue改成stack之外其他的一模一样
然后就304msAC?
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <stack> 6 #define rep(i,l,r) for(int i=l; i<=r; i++) 7 #define clr(x,y) memset(x,y,sizeof(x)) 8 #define travel(x) for(Edge *p=last[x]; p; p=p->pre) 9 using namespace std; 10 typedef long long ll; 11 const int INF = 0x3f3f3f3f; 12 const int maxn = 100010; 13 inline int read(){ 14 int ans = 0, f = 1; 15 char c = getchar(); 16 for(; !isdigit(c); c = getchar()) 17 if (c == ‘-‘) f = -1; 18 for(; isdigit(c); c = getchar()) 19 ans = ans * 10 + c - ‘0‘; 20 return ans * f; 21 } 22 struct Edge{ 23 Edge* pre; int to,cost; 24 }edge[200010],*last[maxn],*pt = edge; 25 int n,k,x,a,b,c,d[maxn],cnt[maxn]; 26 bool isin[maxn]; 27 stack <int> s; 28 inline void addedge(int x,int y,int z){ 29 pt->pre = last[x]; pt->to = y; pt->cost = z; last[x] = pt++; 30 } 31 bool spfa(){ 32 clr(isin,0); 33 rep(i,1,n) d[i] = 0, isin[i] = 1, s.push(i), cnt[i] = 1; 34 while (!s.empty()){ 35 int now = s.top(); s.pop(); isin[now] = 0; 36 travel(now){ 37 if (d[p->to] > d[now] + p->cost){ 38 d[p->to] = d[now] + p->cost; 39 if (!isin[p->to]){ 40 if (++cnt[p->to] > n) return 0; 41 isin[p->to] = 1; s.push(p->to); 42 } 43 } 44 } 45 } 46 return 1; 47 } 48 int main(){ 49 n = read(); k = read(); 50 rep(i,1,k){ 51 x = read(); 52 switch(x){ 53 case 1: a = read(), b = read(), c = read(), addedge(a,b,-c); break; 54 case 2: a = read(), b = read(), c = read(), addedge(b,a,c); break; 55 case 3: a = read(), b = read(), addedge(a,b,0), addedge(b,a,0); break; 56 } 57 } 58 printf(spfa() ? "Yes\n" : "No\n"); 59 return 0; 60 }
以上是关于BZOJ3436 小K的农场的主要内容,如果未能解决你的问题,请参考以下文章