矩阵「BZOJ4500」
这是一道用图论来做的题目,但用数学分析能拘到AC。
数学
#include<bits/stdc++.h> using namespace std; long long T; long long m,n,k; long long s[1111][1111]; long long cnt[1111][1111]; struct node{ long long x,y,w; }v[1111]; bool cmp(node a,node b){ if(a.x==b.x){ return a.y<b.y; }else{ return a.x<b.x; } } int main(){ cin>>T; while(T--){ memset(s,0,sizeof(s)); memset(cnt,0,sizeof(cnt)); scanf("%d %d %d", &m,&n,&k); bool tmp=0; for(long long i=1;i<=k;i++){ scanf("%d %d %d", &v[i].x,&v[i].y,&v[i].w); if(!cnt[v[i].x][v[i].y]){ s[v[i].x][v[i].y]=v[i].w; cnt[v[i].x][v[i].y]=1; }else{ if(s[v[i].x][v[i].y]!=v[i].w){ tmp=1; } } } sort(v+1,v+k+1,cmp); bool fg=0; for(long long a=1;a<=k;a++){ for(long long b=a+1;b<=k;b++){ for(long long c=b+1;c<=k;c++){ if(v[a].x==v[b].x&&v[a].y==v[c].y){ long long xx=v[c].x; long long yy=v[b].y; if(cnt[xx][yy]){ if((v[a].w+v[b].w+v[c].w+s[xx][yy])%2!=0){ fg=1; break; } } } } } } if(!fg&&!tmp){ puts("Yes"); }else{ puts("No"); } } return 0; }
图论
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll t,m,n,k; ll head[2100012],to[2100012],pre[2100012],val[2100012],len; ll dis[2100012],nxt[2100012]; bool vis[2100012]; void insert(ll u,ll v,ll w){ to[++len]=v; val[len]=w; pre[len]=head[u]; head[u]=len; } bool xy(){ queue<ll>pq; memset(dis,0x3f3f3f3f,sizeof(dis)); memset(vis,0,sizeof(vis)); memset(nxt,0,sizeof(nxt)); dis[0]=0; vis[0]=1; pq.push(0); while(!pq.empty()){ ll now=pq.front(); pq.pop(); for(ll i=head[now];i;i=pre[i]){ ll nex=to[i]; if(dis[nex]>dis[now]+val[i]){ dis[nex]=dis[now]+val[i]; nxt[nex]=nxt[now]+1; if(nxt[nex]>=m+n+1){ return false; } if(!vis[nex]){ vis[nex]=true; pq.push(nex); } } } vis[now]=false; } return true; } int main(){ scanf("%lld",&t); while(t--){ scanf("%lld %lld %lld",&m,&n,&k); memset(head,0,sizeof(head)); memset(to,0,sizeof(to)); memset(pre,0,sizeof(pre)); len=0; for(ll i=1;i<=m+n;i++){ insert(0,i,0); } for(ll i=1;i<=k;i++){ ll x,y,c; scanf("%lld %lld %lld",&x,&y,&c); insert(x,y+m,c); insert(y+m,x,-c); } if(xy()){ puts("Yes"); }else{ puts("No"); } } return 0; }