bzoj4500 -- 差分约束

令a[i]表示第i行总共加了a[i],a[j]表示第j列总共加了a[j],得到k个方程:

a[i1]+a[j1]=c1

a[i2]+a[j2]=c2

...

a[ik]+a[jk]=ck

将i,j看成点,一遍dfs求出a并判断是否合法即可。

 

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 #define N 2010
 7 struct Edge{
 8     int nx,t,w;
 9 }e[N];
10 int i,j,k,n,m,x,y,z,d[N],T,Num,h[N];
11 bool b[N],f;
12 inline void Add(int x,int y,int z){e[++Num].t=y;e[Num].nx=h[x];e[Num].w=z;h[x]=Num;}
13 inline void Dfs(int x){
14     if(!f)return;b[x]=1;
15     for(int i=h[x];i;i=e[i].nx)
16     if(!b[e[i].t]){
17         d[e[i].t]=e[i].w-d[x];
18         Dfs(e[i].t);
19     }else if(d[e[i].t]+d[x]!=e[i].w){
20         f=0;break;
21     }
22 }
23 int main(){
24     scanf("%d",&T);
25     while(T--){
26         scanf("%d%d%d",&n,&m,&k);
27         memset(b,0,sizeof(b));f=1;
28         for(i=1,Num=0;i<=n+m;i++)h[i]=0;
29         for(i=1;i<=k;i++)scanf("%d%d%d",&x,&y,&z),Add(x,n+y,z),Add(n+y,x,z);
30         for(i=1;i<=n+m;i++)
31         if(!b[i]){
32             Dfs(i);
33             if(!f){
34                 puts("No");
35                 break;
36             }
37         }
38         if(i>n+m)puts("Yes");
39     }
40     return 0;
41 }
bzoj4500

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值