之前的博客markdown出锅了 ̄□ ̄||,又重新写了一遍
题意就是一个$n$ $\times$ $m$的矩阵,一开始全是零,你可以个每一行或每一列都加1或减1,要求特定区域的值与要求值相等
我们设$x_i$为第$i$行的数变化的多少,设$y_j$为第$j$列的数变化的多少,如果我们要求第$i$行,第$j$列的数为$x$,那么我们可以得到
$x_i$-$y_j$=$num$转换成不等式得到$\begin{cases}x_i-y_j \le num\\y_j-x_i \le -num \end{cases}$满足差分约束条件
PS.差分约束本来是专门写了博客讲的,但是写糊了,就不打算重新写了,直接粘代码:
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <queue> 5 #include <cstring> 6 #define inl inline 7 #define reg register 8 using namespace std; 9 int t,n,m,k; 10 int x,y,c; 11 struct node{ 12 int to,w,next; 13 }ed[1000005]; 14 int head[1000005],tot[1000005],dis[1000005],vis[1000005],cnt; 15 inl void add(int u,int v,int w){ 16 ed[++cnt].to=v; 17 ed[cnt].w=w; 18 ed[cnt].next=head[u]; 19 head[u]=cnt; 20 } 21 inl bool spfa(int s){ 22 queue<int> q; 23 q.push(s);memset(vis,0,sizeof(vis)); 24 for(int i = 1 ; i <= m + n ; ++i) dis[i] = 2003518617; 25 dis[s]=0;vis[s]=1; 26 while (!q.empty()){ 27 int x=q.front(); 28 q.pop();vis[x]=0; 29 for (reg int i = head[x];i;i=ed[i].next){ 30 int to=ed[i].to; 31 if (dis[to]>dis[x]+ed[i].w){ 32 dis[to]=dis[x]+ed[i].w; 33 if (!vis[to]){ 34 vis[to]=1;tot[to]++; 35 if (tot[to]==n + m) return false; 36 q.push(to); 37 } 38 } 39 } 40 } 41 return true; 42 } 43 int main(){ 44 scanf ("%d",&t); 45 while (t--){ 46 memset(head,0,sizeof(head));cnt=0;memset(ed,0,sizeof(ed));memset(tot,0,sizeof(tot)); 47 scanf ("%d%d%d",&n,&m,&k); 48 for (reg int i = 1;i <= n+m;i++) add(0,i,0); 49 for (reg int i = 1;i <= k;i++){ 50 scanf ("%d%d%d",&x,&y,&c); 51 add(x,y+n,c);add(y+n,x,-c); 52 } 53 if (!spfa(0)) cout<<"No"<<endl; 54 else cout<<"Yes"<<endl; 55 } 56 return 0; 57 }