BZOJ4500 matrix

Description

A matrix of n * m, the initial weight of each bin is 0, the matrix can perform two operations:

  1. Select a row, the row weight of each grid value plus 1 or minus 1.
  2. Select one, the column weight of each bin value plus 1 or minus 1.
    There are K limitation, each limited to a triplet (x, y, c), the representative grid (x, y) is equal to the weight c. Asking whether there is a sequence of operations, so that after the matrix operation satisfies all limits. If there is output "Yes", otherwise a "No".

Input

First input a T (T <= 5) with a T group represents the input data, each data format:
The first line of three integers n, m, k (1 < = n, m, k <= 1000).
Next k rows, each row of three integers x, y, c.

Output

For each test, output Yes or No.

Sample Input

2

2 2 4

1 1 0

1 2 0

2 1 2

2 2 2

2 2 4

1 1 0

1 2 0

2 1 2

2 2 1

Sample Output

Yes

No

answer

Indicates the operation with the i-th row Xi, Yj represents the j-th column operation, for (i, j, C) have X- i + the Y j = C

c<=Xi+Yj<=c-->(-Yj)+c<=Xi     Xi-c<=(-Yj)

Spfa then ran up the road to forfeit ring, pay attention to the beginning of all points in the queue, preventing some point can not be traversed

Hu purely mouth, because there is no authority can not pay

#include<bits/stdc++.h>
using namespace std;

const int maxn=2005;
int t,n,m,k;
int cnt,head[maxn],cx[maxn];
struct edge{
    int y,val,next;
}e[maxn<<1];

void add(int x,int y,int z){
    e[++cnt]=(edge){y,z,head[x]};
    head[x]=cnt;
}

int dis[maxn];
queue<int> q;
bool vis[maxn];

bool spfa(){
    while(!q.empty()) q.pop();
    for(int i=1;i<=n+m;i++) q.push(i),dis[i]=0,cx[i]=1,vis[i]=true;
    while(!q.empty()){
        int x=q.front();
        q.pop();
        vis[x]=false;
        if(cx[x]>=n+m) return true;
        for(int i=head[x];i;i=e[i].next){
            int y=e[i].y,val=e[i].val;
            if(dis[y]<dis[x]+val){
                dis[y]=dis[x]+val;
                if(!vis[y]){
                    q.push(y);vis[y]=true;
                    if(++cx[y]>=n+m) return true;
                }
            }
        }
    }
    return false;
}

void nice(){
    cnt=0;
    memset(head,0,sizeof(head));
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=k;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        //z<=x+y<=z
        //z<=x-(-y)<=z
        //(-y)+z<=x    x-z<=(-y)
        add(y+n,x,z);add(x,y+n,-z);
    }
    printf("%s\n", spfa() ? "No" : "Yes" );
}

int main(){
    scanf("%d",&t);
    while(t--) nice();
}
View Code

 

Guess you like

Origin www.cnblogs.com/sto324/p/11208875.html