BZOJ 4500: 矩阵 带权并查集

这个思路挺巧妙的 ~ 

定义一行/列的权值为操作后所整体增加的值.   

那么,我们会有若干个 $a[x]+b[y]=c$ 的限制条件.  

但是呢,我们发现符号是不能限制我们的(因为可加可减)  

所以可以将限制条件转化为 $a[x]-b[y]=c$.   

这个用带权并查集就可以方便地维护了~   

code: 

#include <bits/stdc++.h>  
#define N 2006  
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std; 
int p[N],dis[N],z[N],x[N],y[N];   
int find(int x) 
{
    if(p[x]==x)  return x;   
    int rt=find(p[x]);    
    dis[x]=dis[x]+dis[p[x]];      
    p[x]=rt;   
    return rt;      
}
void solve() 
{
    int n,m,k,i,j; 
    scanf("%d%d%d",&n,&m,&k);           
    for(i=1;i<=k;++i)  scanf("%d%d%d",&x[i],&y[i],&z[i]),y[i]+=n;     
    for(i=1;i<=n+m;++i)   p[i]=i, dis[i]=0;    
    for(i=1;i<=k;++i) 
    {
        int xx=find(x[i]), yy=find(y[i]);   
        if(xx!=yy) 
        {   
            p[xx]=yy;   
            dis[xx]=z[i]+dis[y[i]]-dis[x[i]];               
        }  
        else if(dis[x[i]]-dis[y[i]]!=z[i])  break; 
    }  
    if(i>k) printf("Yes\n"); 
    else printf("No\n");   
}
int main() 
{ 
    // setIO("input");      
    int T; 
    scanf("%d",&T); 
    while(T--) solve(); 
    return 0; 
}

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值