• bzoj4500 矩阵


    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。
    设x[i]=选择一行,该行每个格子的权值减1的次数-选择一行,该行每个格子的权值加1的次数
    y[i]=选择一列, 该列每个格子的权值加1的次数-选择一列, 该列每个格子的权值减1的次数
    每个约束条件即x[i]+c[i]=y[i]
    建图,任意构造一个可行方案检查是否与条件矛盾
    #include<cstdio>
    int t,n,m,k;
    int es[10000],enx[10000],e0[10000],ep=2;
    int v[10000],ev[10000];
    bool d[10000];
    void addedge(int x,int y,int f){
        es[ep]=y;enx[ep]=e0[x];ev[ep]=f;e0[x]=ep++;
        es[ep]=x;enx[ep]=e0[y];ev[ep]=-f;e0[y]=ep++;
    }
    bool flag;
    void dfs(int w){
        d[w]=1;
        for(int i=e0[w];i&&flag;i=enx[i]){
            int u=es[i];
            if(d[u]){
                if(v[u]!=v[w]+ev[i])flag=0;
            }else{
                v[u]=v[w]+ev[i];
                dfs(u);
            }
        }
    }
    int main(){
        scanf("%d",&t);
        while(t--){
            scanf("%d%d%d",&n,&m,&k);
            ep=2;
            for(int i=1;i<=n+m;i++)d[i]=e0[i]=v[i]=0;
            for(int i=0,x,y,c;i<k;i++){
                scanf("%d%d%d",&x,&y,&c);
                addedge(x+n,y,c);
            }
            flag=1;
            for(int i=1;flag&&i<=n+m;i++){
                if(!d[i])dfs(i);
            }
            puts(flag?"Yes":"No");
        }
        return 0;
    }
  • 相关阅读:
    [kuangbin带你飞]专题十二 基础DP1 E
    hdu 1203 I NEED A OFFER! (01背包)
    hdu 2602 Bone Collector (01背包)
    hdu 4513 吉哥系列故事——完美队形II (manacher)
    hdu 2203 亲和串 (KMP)
    hdu 1686 Oulipo (KMP)
    hdu 1251 统计难题 (字典树)
    hdu 2846 Repository (字典树)
    hdu 1711 Number Sequence (KMP)
    poj 3461 Oulipo(KMP)
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5365558.html
Copyright © 2020-2023  润新知