zoukankan      html  css  js  c++  java
  • 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。

    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

    题解

    用Xi表示第i行的操作,Yj表示第j列的操作,对于(i,j,c)就有Xi+Yj=c

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

    再用spfa跑最长路判负环即可,注意一开始将所有点放入队列,防止有些点不能遍历到

    纯属口胡,因为没有权限交不了

    #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
    ", spfa() ? "No" : "Yes" );
    }
    
    int main(){
        scanf("%d",&t);
        while(t--) nice();
    }
    View Code
  • 相关阅读:
    第一章 数据集散地:数据库
    第六章 使用ADO.NET查询和操作数据
    第五章 使用ADO.NET访问数据库
    第四章 深入C#的String类
    IOS框架和服务
    一步步调试解决iOS内存泄漏
    app跳转
    iOS 视频直播
    学习心得
    iOS中FMDB的使用
  • 原文地址:https://www.cnblogs.com/sto324/p/11208875.html
Copyright © 2011-2022 走看看