bzoj4500 矩陣 差分約束系統

2021-08-30 13:56:20 字數 1431 閱讀 2065

有乙個n*m的矩陣,初始每個格仔的權值都為0,可以對矩陣執行兩種操作:

1.選擇一行,該行每個格仔的權值加1或減1。

2.選擇一列,該列每個格仔的權值加1或減1。

現在有k個限制,每個限制為乙個三元組(x,y,c),代**子(x,y)權值等於c。

問是否存在乙個操作序列,使得操作完後的矩陣滿足所有的限制。

如果存在輸出」yes」,否則輸出」no」。

先輸入乙個t(t <= 5)代表輸入有t組資料,每組資料格式為:

第一行三個整數n, m, k (1 <= n, m,k <= 1000)。

接下來k行,每行三個整數x, y, c。

我是誰,差分約束是啥,這是哪

考慮記行操作為x,列操作為y,那麼乙個限制等價於x[i]+y[j]=c

轉換一下就是x[i]-(-y[j])<=c,-y[j]-x[i]<=-c

注意到這個和最短路的鬆弛條件很像,即最短路上滿足dis[y]-dis[x]<=w[x][y]

那麼對於這種形式的限制連邊y[j]到x[i]跑最短路就行了。不需要輸出方案就判環嘛

#include

#include

#include

#include

#define rep(i,st,ed) for (int i=st;i<=ed;++i)

#define fill(x,t) memset(x,t,sizeof(x))

const

int n=

4005

;const

int e=

10005

;struct edge e[e]

;bool vis[n]

;int dis[n]

,cnt[n]

;int ls[n]

,edcnt;

intread()

void

add_edge

(int x,

int y,

int w)

; ls[x]

=edcnt;

}bool

spfa

(int st)

}} vis[now]

=false;}

return

false;}

intmain

(void

)fill

(dis,63)

;fill

(cnt,0)

;bool flag=

false

;rep

(i,1

,n+m)

if(dis[i]

==dis[0]

) flag?

puts

("no"):

puts

("yes");

}return0;

}

BZOJ 4500 矩陣 差分約束

4500 矩陣 有乙個n m的矩陣,初始每個格仔的權值都為0,可以對矩陣執行兩種操作 選擇一行,該行每個格仔的權值加1或減1。選擇一列,該列每個格仔的權值加1或減1。現在有k個限制,每個限制為乙個三元組 x,y,c 代 子 x,y 權值等於c。問是否存在乙個操作序列,使得操作完後的矩陣滿足所有的限制...

BZOJ4500 矩陣(差分約束)

bzoj 然而許可權題 顯然拆分行和列。不妨設這一行 列總共加減的值是 p 那麼每乙個限制就是兩個數的和為乙個特定的數。這樣子不好做,反正是乙個二分圖,那麼把列的 p 變成 p 這樣就變成了差是乙個定製,直接差分約束判斷一下就好了。include includeusing namespace std...

BZOJ 4500 矩陣 差分約束

從行向列建邊,代表乙個格仔a i j 對每個頂點的所有操作可以合併在一起用sum xi 表示,那麼題目相當於是要求sum xi sum xj a xi xj 等價於 sum xj sum xi a xi xj 等價於 sum xj sum xi a xi xj sum xj sum xi a xi ...