12分TLE求助
查看原帖
12分TLE求助
123383
未知名网友楼主2021/12/17 14:22
#include<bits/stdc++.h>
using namespace std;
#define maxn 200005
#define LL long long 
inline int read(){
	char c=getchar();
	int x=0,w=1;
	while(c>'9'||c<'0'){
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=x*10+c-'0';
		c=getchar();
	}
	return x*w ;
}
int n,m;
bool vis[8*maxn];
LL S,T,f,maxflow,mincost,FLAG;
LL dis[8*maxn],pre[8*maxn],last[8*maxn],flow[8*maxn],color[8*maxn];
int dx[5]={0,-1,0,1,0},dy[5]={0,0,1,0,-1},opp[5]={0,3,4,1,2};
inline int id(int x,int y,int k){//0中心点 1上点 2右点 3下点 4左点 
	return (x-1)*m+y+m*n*k;
}
struct Edge{
	LL to,next,flow,dis;
}edge[maxn];
int head[maxn],num_edge; 
deque <int> q;
inline void add(int from,int to,int flow,int dis){
	edge[++num_edge].next=head[from];
	edge[num_edge].to=to;
	edge[num_edge].flow=flow;
	edge[num_edge].dis=dis;
	head[from]=num_edge;
}
inline void Add(int from,int to,int flow,int dis){
	if(FLAG==1){//黑点换方向 
		add(to,from,flow,dis);
		add(from,to,0,-dis);
		return;
	}
	add(from,to,flow,dis);
	add(to,from,0,-dis);
}
inline void build(int flag,int x,int y){
	if(flag==1){//单点型
		Add(id(x,y,0),id(x,y,1),1,0);
		Add(id(x,y,1),id(x,y,2),1,1);
		Add(id(x,y,1),id(x,y,3),1,2);
		Add(id(x,y,1),id(x,y,4),1,1);
	}
	else if(flag==2){//单点型 
		Add(id(x,y,0),id(x,y,2),1,0);
		Add(id(x,y,2),id(x,y,1),1,1);
		Add(id(x,y,2),id(x,y,3),1,1);
		Add(id(x,y,2),id(x,y,4),1,2);
	}
	else if(flag==3){//	L型 
		Add(id(x,y,0),id(x,y,1),1,0);
		Add(id(x,y,0),id(x,y,2),1,0);
		Add(id(x,y,1),id(x,y,3),1,1);
		Add(id(x,y,2),id(x,y,4),1,1);
	}
	else if(flag==4){//单点型 
		Add(id(x,y,0),id(x,y,3),1,0);
		Add(id(x,y,3),id(x,y,1),1,2);
		Add(id(x,y,3),id(x,y,2),1,1);
		Add(id(x,y,3),id(x,y,4),1,1);
	}
	else if(flag==5){//直线型 
		Add(id(x,y,0),id(x,y,1),1,0);
		Add(id(x,y,0),id(x,y,3),1,0);
	}
	else if(flag==6){//	L型 
		Add(id(x,y,0),id(x,y,2),1,0);
		Add(id(x,y,0),id(x,y,3),1,0);
		Add(id(x,y,3),id(x,y,1),1,1);
		Add(id(x,y,2),id(x,y,4),1,1);
	}
	else if(flag==7){//T型 
		Add(id(x,y,0),id(x,y,1),1,0);
		Add(id(x,y,0),id(x,y,2),1,0);
		Add(id(x,y,0),id(x,y,3),1,0);
		Add(id(x,y,1),id(x,y,4),1,1);
		Add(id(x,y,2),id(x,y,4),1,2);
		Add(id(x,y,3),id(x,y,4),1,1);
	}
	else if(flag==8){//单点型
		Add(id(x,y,0),id(x,y,4),1,0);
		Add(id(x,y,4),id(x,y,1),1,1);
		Add(id(x,y,4),id(x,y,2),1,2);
		Add(id(x,y,4),id(x,y,3),1,1);
	}
	else if(flag==9){//	L型 
		Add(id(x,y,0),id(x,y,1),1,0);
		Add(id(x,y,0),id(x,y,4),1,0);
		Add(id(x,y,1),id(x,y,3),1,1);
		Add(id(x,y,4),id(x,y,2),1,1);
	}
	else if(flag==10){//直线型 
		Add(id(x,y,0),id(x,y,2),1,0);
		Add(id(x,y,0),id(x,y,4),1,0);
	}
	else if(flag==11){//T型 
		Add(id(x,y,0),id(x,y,1),1,0);
		Add(id(x,y,0),id(x,y,2),1,0);
		Add(id(x,y,0),id(x,y,4),1,0);
		Add(id(x,y,1),id(x,y,3),1,2);
		Add(id(x,y,2),id(x,y,3),1,1);
		Add(id(x,y,4),id(x,y,3),1,1);
	}
	else if(flag==12){//	L型 
		Add(id(x,y,0),id(x,y,3),1,0);
		Add(id(x,y,0),id(x,y,4),1,0);
		Add(id(x,y,3),id(x,y,1),1,1);
		Add(id(x,y,4),id(x,y,2),1,1);
	}
	else if(flag==13){//T型 
		Add(id(x,y,0),id(x,y,1),1,0);
		Add(id(x,y,0),id(x,y,3),1,0);
		Add(id(x,y,0),id(x,y,4),1,0);
		Add(id(x,y,1),id(x,y,2),1,1);
		Add(id(x,y,3),id(x,y,2),1,1);
		Add(id(x,y,4),id(x,y,2),1,2);
	}
	else if(flag==14){//T型 
		Add(id(x,y,0),id(x,y,2),1,0);
		Add(id(x,y,0),id(x,y,3),1,0);
		Add(id(x,y,0),id(x,y,4),1,0);
		Add(id(x,y,2),id(x,y,1),1,1);
		Add(id(x,y,3),id(x,y,1),1,2);
		Add(id(x,y,4),id(x,y,1),1,1);
	}
	else if(flag==15){//T型 
		Add(id(x,y,0),id(x,y,1),1,0);
		Add(id(x,y,0),id(x,y,2),1,0);
		Add(id(x,y,0),id(x,y,3),1,0);
		Add(id(x,y,0),id(x,y,4),1,0);
	}
	if(FLAG==0){//白点向黑点连边 
		for(int i=1;i<=4;i++){
			if(x+dx[i]>=1&&y+dy[i]>=1&&x+dx[i]<=n&&y+dy[i]<=m){
				Add(id(x,y,i),id(x+dx[i],y+dy[i],opp[i]),1,0);
			}
		}
	}
}
inline bool spfa(int s,int t){
	memset(dis,0x7f,sizeof(dis));
	memset(flow,0x7f,sizeof(flow));
	memset(vis,0,sizeof(vis));
	q.push_front(s); vis[s]=1; dis[s]=0; pre[t]=-1;
	while (!q.empty()){
		int now=q.front();
		q.pop_front();
		vis[now]=0;
		for (int i=head[now]; i!=-1; i=edge[i].next){
			if (edge[i].flow>0 && dis[edge[i].to]>dis[now]+edge[i].dis){
				dis[edge[i].to]=dis[now]+edge[i].dis;
				pre[edge[i].to]=now;
				last[edge[i].to]=i;
				flow[edge[i].to]=min(flow[now],edge[i].flow);
				if (!vis[edge[i].to]){
					vis[edge[i].to]=1;
					if(!q.empty()&&dis[edge[i].to]<dis[q.front()]){
						q.push_front(edge[i].to);
					}
					else{
						q.push_back(edge[i].to);
					}
				}
			}
		}
	}
	return pre[t]!=-1;
}
void MCMF(){
	while (spfa(S,T)){
		int now=T;
		maxflow+=flow[T];mincost+=flow[T]*dis[T];
		while (now!=S){
			edge[last[now]].flow-=flow[T];
			edge[last[now]^1].flow+=flow[T];
			now=pre[now];
		}
	}
}
int main(){
	memset(head,-1,sizeof(head)); num_edge=-1;//初始化 
	int x,s,sum=0;
	n=read();
	m=read();
	S=0;
	T=m*n*5+1;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			x=read();
			if(x==0){
				continue;
			}
			s=0;
			if(x&1){s++;}
			if(x&2){s++;}
			if(x&4){s++;}
			if(x&8){s++;}
			FLAG=0;
			if((i+j)&1){//黑点 
				Add(id(i,j,0),T,s,0);
				FLAG=1;
				build(x,i,j);
				sum+=s;
			}
			else{//白点 
				Add(S,id(i,j,0),s,0);
				build(x,i,j);
				sum+=s;
			}
		}
	}
	MCMF();
	if(maxflow<(sum)/2){
		cout<<"-1";
	}
	else{
		cout<<mincost; 
	}
	return 0;
}
/*
1  0001 
2  0010
3  0011
4  0100
5  0101
6  0110
7  0111
8  1000
9  1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
*/
2021/12/17 14:22
加载中...