题面
https://www.luogu.org/problem/P3756
题解
四分图$+$ 花式染色
#include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<vector> #include<map> #include<utility> #define ri register int #define N 200050 #define INF 1000000007 #define S 0 #define T (cc+1) using namespace std; const int dx[]={0,1,0,-1},dy[]={1,0,-1,0}; int n,r,c,x[N],y[N],z[N]; int in[N],ou[N],cc; map<pair<int,int>,int> s; struct graph { vector<int> ed[N]; vector<int> w,to; int d[N],cur[N]; void add_edge(int u,int v,int tw) { to.push_back(v); w.push_back(tw); ed[u].push_back(to.size()-1); to.push_back(u); w.push_back(0) ; ed[v].push_back(to.size()-1); } bool bfs() { queue<int> q; memset(d,0x3f,sizeof(d)); d[S]=0; q.push(S); while (!q.empty()) { int x=q.front(); q.pop(); for (ri i=0;i<ed[x].size();i++) { int e=ed[x][i]; if (d[x]+1<d[to[e]] && w[e]) { d[to[e]]=d[x]+1; q.push(to[e]); } } } return d[T]<INF; } int dfs(int x,int limit) { if (x==T || limit==0) return limit; int sum=0; for (ri &i=cur[x];i<ed[x].size();i++) { int e=ed[x][i]; if (w[e] && d[x]+1==d[to[e]]) { int f=dfs(to[e],min(limit,w[e])); if (!f) continue; sum+=f; limit-=f; w[e]-=f; w[1^e]+=f; if (!limit) return sum; } } return sum; } int dinic() { int ret=0; while (bfs()) { memset(cur,0,sizeof(cur)); ret+=dfs(S,INF); } return ret; } } G; int col(int x,int y) { if (y%2==0) { if (x%4==0) return 4; else if (x%4==1) return 3; else if (x%4==2) return 2; else if (x%4==3) return 1; } else { if (x%4==0) return 3; else if (x%4==1) return 4; else if (x%4==2) return 1; else if (x%4==3) return 2; } } int main() { scanf("%d %d %d",&c,&r,&n); for (ri i=1;i<=n;i++) { scanf("%d %d %d",&x[i],&y[i],&z[i]); if (col(x[i],y[i])==3) ou[i]=in[i]=++cc; else if (col(x[i],y[i])==4) in[i]=++cc,ou[i]=++cc,G.add_edge(in[i],ou[i],z[i]); else if (col(x[i],y[i])==1) in[i]=++cc,ou[i]=++cc,G.add_edge(in[i],ou[i],z[i]); else if (col(x[i],y[i])==2) ou[i]=in[i]=++cc; s[make_pair(x[i],y[i])]=i; } for (ri i=1;i<=n;i++) { if (col(x[i],y[i])==3) G.add_edge(S,in[i],z[i]); else if (col(x[i],y[i])==2) G.add_edge(ou[i],T,z[i]); } int pe[5]; pe[3]=4; pe[4]=1; pe[1]=2; for (ri i=1;i<=n;i++) if (col(x[i],y[i])!=2) { for (ri j=0;j<4;j++) { int nx=x[i]+dx[j],ny=y[i]+dy[j]; int t=s[make_pair(nx,ny)]; if (t>=1 && t<=n && col(nx,ny)==pe[col(x[i],y[i])]) G.add_edge(ou[i],in[t],INF); } } cout<<G.dinic()<<endl; }