BZOJ 4500: 矩阵 差分约束

4500: 矩阵

题目连接:

http://www.lydsy.com/JudgeOnline/problem.php?id=4500

Description

有一个n*m的矩阵,初始每个格子的权值都为0,可以对矩阵执行两种操作:

  1. 选择一行, 该行每个格子的权值加1或减1。
  2. 选择一列, 该列每个格子的权值加1或减1。
    现在有K个限制,每个限制为一个三元组(x,y,c),代表格子(x,y)权值等于c。问是否存在一个操作序列,使得操作完后的矩阵满足所有的限制。如果存在输出”Yes”,否则输出”No”。

Input

先输入一个T(T <= 5)代表输入有T组数据,每组数据格式为:
第一行三个整数n, m, k (1 <= n, m,k <= 1000)。
接下来k行,每行三个整数x, y, c。

Output

对于每组数据,输出Yes或者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

Hint

题意

题解:

简单想一想,其实发现就是2000个点的差分约束,然后跑一遍dfs就好了

x,y,z表示x+z=y,y-z=x,然后建边就好了

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2005;
vector<pair<int,int> > E[maxn];
int n,m,k;
int vis[maxn],d[maxn];
int flag;
void init()
{
    for(int i=0;i<maxn;i++)E[i].clear();
    memset(vis,0,sizeof(vis));
    memset(d,0,sizeof(d));
}
void dfs(int x)
{
    if(flag)return;
    if(!vis[x])vis[x]=1;
    for(int i=0;i<E[x].size();i++)
    {
        pair<int,int>v = E[x][i];
        if(!vis[v.first])
        {
            d[v.first]=d[x]+v.second;
            dfs(v.first);
        }
        else
        {
            if(d[v.first]!=d[x]+v.second)
                flag=1;
        }
    }
}
void solve()
{
    init();
    flag = 0;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=0;i<k;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        E[x].push_back(make_pair(n+y,z));
        E[n+y].push_back(make_pair(x,-z));
    }

    for(int i=1;i<=n;i++)
        if(!vis[i])
            dfs(i);
    if(flag)printf("No\n");
    else printf("Yes\n");
}
int main()
{
    int t;scanf("%d",&t);
    while(t--)solve();
    return 0;
}
posted @ 2016-04-12 08:50  qscqesze  阅读(1073)  评论(0编辑  收藏  举报