P1993 小K的農場 題解

2022-03-15 16:35:34 字數 1373 閱讀 8297

這是一道差分約束的題不會差分約束系統的人請往這邊走

差分約束系統,其形式非常像單源最短路的三角形不等式,所以已圖論演算法來列出方程(我是按求至少值得演算法來求的,求最大值相反)

\[\left\ & a-b \geq c(k=1)& \\ & b-a \geq c (k=2)& \\ & a-b \geq 0, b-a \geq 0(k=3) & \end\right.

\]如果建的圖有負環(跑最長路求正環),即小k抽了記錯了。

這題我原來打的是基於bfs_spfa,然後超時了,spfa又死了, 覺得我變菜了雖然dfs_spfa好用但是複雜度還是指數級的,特別有可能被毒瘤出題人卡過容易tle,所以因為題目資料範圍是\(n,m \leq 10000\) 所以我可以分兩中方案,如果為\(n * m \geq 1e+7\),那麼就懸著dfs_spfa,如果不滿足,選擇珂學的方法bfs_spfa,

bfs_spfa的找負環

記乙個陣列為\(cnt[i]\),表示經過的邊數,如果\(cnt[i]\geq m\),即出現負環,這種方法效率很高但是最壞為o(nm)還是死,比網上很多犧牲正確性來跑有時得不償失的演算法好多了。

**實現我知道你們最喜歡這個:

#include#include#include#include#define re register

using namespace std;

templateinline void read(t&x)

while(s>='0'&&s<='9')

if(f)

x=(~x)+1;

}const int n=1000010;

int dis[n];

struct edge

edge[n];

int num_edge,head[n],n,m,cnt[n],*v,*w;

bool exist[n];

inline void add_edge(const int&from,const int&to,const int&dis)

inline void dfs_spfa(int u)

if(!exist[*v])

}} }

while(!q.empty());

printf("yes\n");

}int main()

else if(k==2)

else if(k==3)

}for(re int i=1; i<=n; i++)

add_edge(0,i,0);

if(n*m>=1e7)

else

bfs_spfa();

return 0;

}

如果差分約束系統已經有很大的基礎,建議去做

[scoi2011]糖果

和出納員問題

P1993 小K的農場

小k在mc裡面建立很多很多的農場,總共n個,以至於他自己都忘記了每個農場中種植作物的具體數量了,他只記得一些含糊的資訊 共m個 以下列三種形式描述 但是,由於小k的記憶有些偏差,所以他想要知道存不存在一種情況,使得農場的種植作物數量與他記憶中的所有資訊吻合。輸入格式 第一行包括兩個整數 n 和 m,...

P1993 小k的農場

小k在mc裡面建立很多很多的農場,總共n個,以至於他自己都忘記了每個農場中種植作物的具體數量了,他只記得一些含糊的資訊 共m個 以下列三種形式描述 但是,由於小k的記憶有些偏差,所以他想要知道存不存在一種情況,使得農場的種植作物數量與他記憶中的所有資訊吻合。第一行包括兩個整數 n 和 m,分別表示農...

洛谷P1993 小K的農場

小k在mc裡面建立很多很多的農場,總共n個,以至於他自己都忘記了每個農場中種植作物的具體數量了,他只記得一些含糊的資訊 共m個 以下列三種形式描述 但是,由於小k的記憶有些偏差,所以他想要知道存不存在一種情況,使得農場的種植作物數量與他記憶中的所有資訊吻合。輸入格式 第一行包括兩個整數 n 和 m,...