zoukankan      html  css  js  c++  java
  • AT2033 【マス目と整数 / Grid and Integers】

    AT2033 【マス目と整数 / Grid and Integers】

    题意

    给定一个 $ R imes C $ 的矩阵,有一些位置的数已经被固定了,每个格子中只能有非负整数

    询问是否有一种填数方案使得任意一个$ 2 imes 2 $ 的子矩阵中有对角线之和相等

    题解

    考虑化简题目要求
        
       $ a_{i,j} + a_{i+1,j+1} = a_{i+1,j} + a_{i,j+1} $
       
       $ a_{i,j} - a_{i,j+1} = a_{i+1,j+1} - a_{i+1,j+1} $

    同理有

     $ a_{i,j} - a_{i+1,j} = a_{i,j+1} - a_{i+1,j+1} $

    考虑构造 $ a_{i,j} = x_i + y_j $

    如果存在可能的x序列和y序列

    那么对于每个子矩阵限制条件一定满足

    则原问题转化为给定一些形如 $ x_i + y_j = val_k $ 的限制,能否构造出符合条件的序列

    显然任意两个 $x_i$ 之间都不影响 同理$y_i$也是

    于是考虑连边,所成图一定是若干个个二分图

    考虑给每个节点染色使得点权之和等于边权

    按照套路,先尝试不考虑非负的限制,随便构造出一组方案

    显然随便找一个点赋个权值进行染色即可,显然如果没有限制相互矛盾这样一定可以构造出一种方案

    之后考虑调整一波,使得每个点非负,把每个二分图的搜索树画出来,容易发现对于一个点x,如果一个点增加了K,那么为了满足限制条件,所有点都会相应的加K或减K

    所以只要在一种构造方案中有最小的 $x_i$ 和 $y_i$相加为非负数就一定有可行方案

    代码很简单

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define LL long long
    
    inline LL read()
    {
        LL f = 1,x = 0;
        char ch;
        do
        {
            ch = getchar();
            if(ch == '-') f = -1;
        }while(ch < '0'||ch > '9');
        do
        {
            x = (x<<3) + (x<<1) + ch - '0';
            ch = getchar();
        }while(ch >= '0' && ch <= '9');
        return f*x;
    } 
    
    const int MAXN = 100000 + 10;
     
    int R,C;
    int N;
    bool vis[MAXN<<1];
    vector<pair<int,LL> >G[MAXN<<1];
    LL col[MAXN<<1];
    int rt[MAXN<<1],tot;
    vector<int>Sta[MAXN<<1];
    
    inline bool dfs(int x)
    {
        vis[x] = 1;
        Sta[tot].push_back(x);
        bool flag = 1;
        for(int i=0;i<G[x].size();i++)
        {
            LL v = G[x][i].first,w = G[x][i].second;
            if(vis[v]){ if(col[v] + col[x] != w) return false;}
            else
            {
                col[v] = w - col[x];
                flag &= dfs(v);
                if(!flag) return false;
            }
        }
        return flag;
    }
    
    inline bool check(int x)
    {
        LL res1 = 1LL<<62,res2 = 1LL<<62;
        for(int i=0;i<Sta[x].size();i++)
        {
            int v = Sta[x][i];
            if(v > R) res2 = min(res2 , col[v]);
            else res1 = min(res1, col[v]);
        }
        return res1 + res2 >= 0;
    }
    
    int main()
    {
        R = read(),C = read();
        N = read();
        for(int i=1;i<=N;i++)
        {
            int x = read(),y = read(),w = read();
            G[x].push_back(make_pair(y+R,w));
            G[y+R].push_back(make_pair(x,w));
        }
        bool flag = 1;
        for(int i=1;i<=R+C;i++) if(!vis[i]) rt[++tot] = i,col[i] = 0,flag &= dfs(i);
        if(!flag) { printf("No
    ");return 0;}
        for(int i=1;i<=tot;i++) flag &= check(i);
        if(!flag) printf("No
    ");
        else printf("Yes
    "); 
     } 
  • 相关阅读:
    Java使用MyEclipse2017时的一些小细节
    Windows设置双ip访问虚拟机方法
    Python-函数的参数
    Python dict.set
    FTP错误代码列表
    使用批处理文件在FTP服务器 上传下载文件(转载)
    FreeRTOS学习笔记7-FreeRTOS 队列相关
    FreeRTOS学习笔记6-调度器开启和任务相关函数
    从github hexo 跑来 博客园
    Nodejs实战 —— 测试 Node 程序
  • 原文地址:https://www.cnblogs.com/wlzs1432/p/14006374.html
Copyright © 2011-2022 走看看