这道题数据小了吧
查看原帖
这道题数据小了吧
539223
纪子涵20080204楼主2024/1/6 20:52

以下代码点的数量开900,边的数量开6009都能过
而按照数据范围100乘100是不是至少有10000个点

#include<bits/stdc++.h>
#define ll long long
#define INF 1e12
#define E 6009
#define N 909
using namespace std;
const ll dx[5]={0,1,-1,0,0};
const ll dy[5]={0,0,0,1,-1};
ll n,m,nV,S,T;
struct Edge{
	ll to,c,nxt;
} e[E];
ll edge,hd[N];
ll pre[N],flow[N];
ll id(ll x,ll y){
	return (x-1)*n+y;
}
ll re(ll x){
	if(x%2==1) return x+1;
	else return x-1;
}
void add(ll u,ll v,ll c){
	edge++;
	e[edge]=(Edge){v,c,hd[u]};
	hd[u]=edge;
}
bool bfs(){
	fill(pre,pre+1+nV,0);
	queue<ll> q; 
	q.push(S); 
	pre[S]=-1; 
	flow[S]=INF;
	while(!q.empty()){
		ll u=q.front(); q.pop();
		for(ll i=hd[u];i;i=e[i].nxt){
			ll v=e[i].to,c=e[i].c;
			if(!c||pre[v]) continue;
			q.push(v); pre[v]=i; 
			flow[v]=min(flow[u],c);
			if(v==T) return true;
		}
	}
	return false;
}
ll EdmondKarp(){
	ll max_flow=0;
	while(bfs()){
		max_flow+=flow[T];
		for(ll i=T;i!=S;i=e[re(pre[i])].to){
			e[pre[i]].c-=flow[T];
			e[re(pre[i])].c+=flow[T];
		}
	}
	return max_flow;
}
int main(){
	cin>>m>>n;
	S=m*n+1; T=m*n+2; nV=T;
	ll sum=0;
	for(ll i=1;i<=m;i++){
		for(ll j=1;j<=n;j++){
			ll x; cin>>x; sum+=x;
			if((i+j)&1){
				add(S,id(i,j),x);
				add(id(i,j),S,0);
				continue;
			}
			add(id(i,j),T,x);
			add(T,id(i,j),0);
			for(ll k=1;k<=4;k++){
				ll nx=dx[k]+i,ny=dy[k]+j;
				if(nx<1||nx>m||ny<1||ny>n) continue;
				add(id(nx,ny),id(i,j),INF);
				add(id(i,j),id(nx,ny),0);
			}
		}
	}
	cout<<sum-EdmondKarp();
	return 0;
}
2024/1/6 20:52
加载中...