萌新刚学,后面忘了
  • 板块P4003 无限之环
  • 楼主TLEWA
  • 当前回复1
  • 已保存回复1
  • 发布时间2025/1/25 19:12
  • 上次更新2025/1/25 23:29:57
查看原帖
萌新刚学,后面忘了
515129
TLEWA楼主2025/1/25 19:12

你说得对,但是我在 P4003 无限之环 获得了 2pts 的高分,你也来试试吧!

#include<bits/stdc++.h>

using namespace std;

const int N=2005,K=10050,INF=1e9;

int n,m;
int arr[N][N],varr[N][N],ans;

struct Node {int v,w,c,id;};
vector<Node> vec[K];

int S,T;

void add(int u,int v,int w,int c) {
	vec[u].push_back({v,w,c,vec[v].size()});
	vec[v].push_back({u,0,-c,vec[u].size()-1});
}

// 网络流部分
int dis[K],cur[K];
bool vis[K];

queue<int> que;
bool SPFA() {
	memset(dis,63,sizeof(dis));
	memset(cur,0,sizeof(cur));
	dis[S]=0;que.push(S);
	
	int u;
	while(!que.empty()) {
		u=que.front();
		que.pop();vis[u]=0;
		
		for(auto& [v,w,c,id]:vec[u]) {
			if(!w || dis[v]<=dis[u]+c) continue;
			dis[v]=dis[u]+c;
			if(!vis[v]) vis[v]=1,que.push(v);
		}
	}
	
	return dis[T]<INF;
}

int dfs(int u,int flow) {
	if(u==T) return flow;
	vis[u]=1;
	
	int v,c,w,cnt=0,d;
	for(int i=cur[u];i<vec[u].size();++i) {
		cur[u]=i;
		v=vec[u][i].v,w=vec[u][i].w,c=vec[u][i].c;
		if(!vis[v] && dis[v]==dis[u]+c && w) {
			d=dfs(v,min(w,flow-cnt));
			vec[v][vec[u][i].id].w+=d;
			vec[u][i].w-=d;
			cnt+=d,ans+=d*c;
			if(cnt==flow) {vis[u]=0;return cnt;}
		}
	}
	
	vis[u]=0;
	return cnt;
}

int rorate_l(int num) {
	num=num<<1;
	if(num>15) num-=15;
	return num;
}

int rorate_r(int num) {
	if(num&1) num+=15;
	num=num>>1;
	return num;
}

int main() {
	cin >> n >> m;
	for(int i=1;i<=n;++i) {
		for(int j=1;j<=m;++j) {
			cin >> arr[i][j];
		}
	}
	
	int id;S=5*n*m+1,T=5*n*m+2;
	for(int i=1;i<=n;++i) { // 建立通用边 
		for(int j=1;j<=m;++j) {
			id=m*(i-1)+(j-1);
			if((i+j)&1) { // 源点 
				if(i>1) add(5*id+1,5*(id-m)+3,1,0);
				if(i<n) add(5*id+3,5*(id+m)+1,1,0);
				if(j>1) add(5*id+4,5*(id-1)+2,1,0);
				if(j<m) add(5*id+2,5*(id+1)+4,1,0);
				add(S,5*id+5,INF,0);
			}else add(5*id+5,T,INF,0);
		}
	}
	
	bool flg=0;int vis=0;
	auto fadd = [&](int u,int v,int w,int c) -> void {
		if(flg) add(u,v,w,c);
		else add(v,u,w,c);
	};
	
	auto calc = [&](int id,int lst,int now,int cost) -> void {
		int from=(lst&(~now)),to=((~lst)&now);
		if(__builtin_popcount(from)!=1) return;
		if((vis&from) || (to&lst)) return;
		vis|=from;
		fadd(5*id+__builtin_ffs(from),5*id+__builtin_ffs(to),1,cost);
	};
	
	int cnt=0;
	for(int i=1;i<=n;++i) {
		for(int j=1;j<=m;++j) {
			flg=(i+j)&1,vis=0,id=m*(i-1)+(j-1);
			calc(id,arr[i][j],rorate_r(arr[i][j]),1);
			calc(id,arr[i][j],rorate_l(arr[i][j]),1);
			calc(id,arr[i][j],rorate_r(rorate_r(arr[i][j])),2);
			for(int k=1;k<=4;++k)
				if((1<<(k-1))&arr[i][j])
					fadd(5*id+5,5*id+k,1,0),++cnt;
		}
	}
	
	int flow=0;
	while(SPFA()) {
		flow+=dfs(S,INF);
	}
	
//	cout << cnt << ' ' << flow << ' ' << ans << endl;
	
	if(flow*2==cnt) cout << ans;
	else cout << -1;
	
	return 0;
}

求调/kel

2025/1/25 19:12
加载中...