网络流 50pts 求调 TVT
查看原帖
网络流 50pts 求调 TVT
564732
TimSwn090306楼主2024/7/2 12:19

题解区里染色 + 拆点的做法,但是只过了前 50pts50pts。

#include <bits/stdc++.h>
#define fin(str) freopen(str,"r",stdin)
#define fout(str) freopen(str,"w",stdout)
#define ll long long
using namespace std;
const int maxn=3e5+5;
const int inf=0x3f3f3f3f;
struct edge{
	int to,w,next;
}e[maxn<<4];
int tot=1,h[maxn<<4];
inline void addEdge(int x,int y,int z){
	e[++tot]=(edge){y,z,h[x]};
	h[x]=tot;
}
inline void link(int x,int y,int z) {addEdge(x,y,z),addEdge(y,x,0); }
inline int getcol(int x,int y){
	x%=2,y%=4;
	if (!x) x=2;
	if (!y) y=4;
	if ((x==1 && y==4) || (x==2 && y==1)) return 1;
	else if ((x==1 && y==1) || (x==2 && y==4)) return 2;
	else if ((x==1 && y==2) || (x==2 && y==3)) return 3;
	else return 4;
}
int r,c,n,s,t;
int sx[maxn],sy[maxn],w[maxn];
int dx[]={0,-1,0,0,1};
int dy[]={0,0,-1,1,0};
map <int,int> mp[maxn];
inline int get(int x,int layer) {return x+(layer-1)*n; }
int d[maxn<<4],cur[maxn<<4];
queue <int> q;
inline bool bfs(){
	memset(d,-1,sizeof(d));
	memset(cur,0,sizeof(cur));
	d[s]=0;
	q.push(s);
	while (!q.empty()){
		int x=q.front();
		q.pop();
		cur[x]=h[x];
		for (int i=h[x];i;i=e[i].next){
			int v=e[i].to;
			if (e[i].w && d[v]==-1){
				d[v]=d[x]+1;
				q.push(v);
			}
		}
	}
	return d[t]!=-1;
}
inline int dinic(int x,int flow){
	if (x==t) return flow;
	int rest=flow;
	for (int i=cur[x];i&&rest;i=e[i].next){
		int v=e[i].to;
		cur[x]=i;
		if (e[i].w && d[v]==d[x]+1){
			int nw=dinic(v,min(rest,e[i].w));
			if (!nw) d[v]=-1;
			e[i].w-=nw,e[i^1].w+=nw;
			rest-=nw;
		}
	}
	return flow-rest;
}
int main(){
	scanf("%d%d%d",&c,&r,&n);
	s=0,t=get(n,8)+1;
	for (int i=1;i<=n;i++){
		scanf("%d%d%d",&sx[i],&sy[i],&w[i]);
		swap(sx[i],sy[i]);
		mp[sx[i]][sy[i]]=i;
		link(get(i,getcol(sx[i],sy[i])*2-1),get(i,getcol(sx[i],sy[i])*2),w[i]);
	}
	for (int i=1;i<=n;i++){
		int x=sx[i],y=sy[i],c=getcol(sx[i],sy[i]);
		if (c==1) link(s,get(i,getcol(sx[i],sy[i])*2-1),inf);
		if (c==4) link(get(i,getcol(sx[i],sy[i])*2),t,inf);
		for (int k=1;k<=4;k++){
			int xx=x+dx[k],yy=y+dy[k];
			if (xx<1 || xx>r || yy<1 || yy>c || !mp[xx][yy]) continue;
			int cc=getcol(xx,yy);
//			printf("%d %d : col %d\n",xx,yy,cc);
			if (cc==c+1){
				int id=mp[xx][yy];
				link(get(i,getcol(sx[i],sy[i])*2),get(id,getcol(xx,yy)*2-1),inf);
			}
		}
	}
	int ans=0;
	while (bfs()) ans+=dinic(s,inf);
	printf("%d\n",ans);
	return 0;
}

2024/7/2 12:19
加载中...