有一个n*m的矩阵,初始每个格子的权值都为0,可以对矩阵执行两种操作:
1. 选择一行, 该行每个格子的权值加1或减1。
2. 选择一列, 该列每个格子的权值加1或减1。
现在有K个限制,每个限制为一个三元组(x,y,c),代表格子(x,y)权值等于c。问是否存在一个操作序列,使得操作完后的矩阵满足所有的限制。如果存在输出”Yes”,否则输出”No”。
标签:
#include<cstdio> #include<cctype> #include<queue> #include<cstring> #include<algorithm> #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define ren for(int i=first[x];i;i=next[i]) using namespace std; const int BufferSize=1<<16; char buffer[BufferSize],*head,*tail; inline char Getchar() { if(head==tail) { int l=fread(buffer,1,BufferSize,stdin); tail=(head=buffer)+l; } return *head++; } inline int read() { int x=0,f=1;char c=Getchar(); for(;!isdigit(c);c=Getchar()) if(c==‘-‘) f=-1; for(;isdigit(c);c=Getchar()) x=x*10+c-‘0‘; return x*f; } const int maxn=2010; int n,m,vis[maxn],val[maxn],first[maxn],next[maxn<<1],to[maxn<<1],dis[maxn<<1],e; void AddEdge(int u,int v,int w) { to[++e]=v;dis[e]=w;next[e]=first[u];first[u]=e; to[++e]=u;dis[e]=w;next[e]=first[v];first[v]=e; } int dfs(int x) { vis[x]=1; ren { if(vis[to[i]]&&val[to[i]]+val[x]!=dis[i]) return 0; else if(!vis[to[i]]) { val[to[i]]=dis[i]-val[x]; if(!dfs(to[i])) return 0; } } return 1; } void solve() { n=read();m=read();e=0; rep(i,1,n+m) vis[i]=first[i]=0; dwn(i,read(),1) { int x=read(),y=read(),v=read(); AddEdge(x,y+n,v); } rep(i,1,n+m) if(!vis[i]&&!dfs(i)) { puts("No");return; } puts("Yes"); } int main() { dwn(T,read(),1) solve(); return 0; }
标签:
原文地址:http://www.cnblogs.com/wzj-is-a-juruo/p/5514542.html