這是一道差分約束的題不會差分約束系統的人請往這邊走
差分約束系統,其形式非常像單源最短路的三角形不等式,所以已圖論演算法來列出方程(我是按求至少值得演算法來求的,求最大值相反)
\[\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,...