31分新颖WA法
查看原帖
31分新颖WA法
575698
262620zzj楼主2024/6/1 15:47
#include<bits/stdc++.h>
using namespace std;
template<typename T>inline void read(T &x){
	x=0;int f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	x*=f;
}
template<typename T,typename ...Args>
inline void read(T &x,Args &...rest){read(x);read(rest...);}
constexpr int N=10005;
struct edge{int to,nx,c,w;}e[50000];
int head[N],tot=1,should;
inline void add(int u,int v,int w,int ty){
	if(ty)swap(u,v);
    e[++tot]={v,head[u],1,w};
    head[u]=tot;
	e[++tot]={u,head[v],0,-w};
	head[v]=tot;
}
#define repg(i,u,v) for(int i=head[u],v=e[i].to;i;i=e[i].nx,v=e[i].to)
int n,m,s,t;
int now[N],maxcurrent,mincost,dis[N];
bool vis[N];
inline bool spfa(){
	memset(vis,0,sizeof(vis));
	memset(dis,127,sizeof(dis));
	memcpy(now,head,sizeof(head));
	dis[t]=0;
	deque<int> Q;
	Q.push_front(t);
	while(!Q.empty()){
		int u=Q.front();
		Q.pop_front();
		vis[u]=0;
		repg(i,u,v){
			if(e[i^1].c>0&&dis[u]-e[i].w<dis[v]){
				dis[v]=dis[u]-e[i].w;
				if(!vis[v]){
					vis[v]=1;
					if(Q.empty()||dis[v]>dis[Q.front()])Q.push_back(v);
					else Q.push_front(v);
				}
			}
		}
	}
	return dis[s]!=2139062143;
}
inline int dfs(int u,int remain){
	if(u==t)return vis[t]=1,remain;
	int current=0,cap;
	vis[u]=1;
	for(int i=now[u];i&&remain>0;i=e[i].nx){
		int v=e[i].to;
		now[u]=i;
		if(e[i].c==0||vis[v]||dis[u]-e[i].w!=dis[v])continue;
		cap=dfs(v,min(remain,e[i].c));
		e[i].c-=cap;
		e[i^1].c+=cap;
		current+=cap;
		remain-=cap;
		mincost+=cap*e[i].w;
	}
	return current;
}
inline void MCMC(){
	while(spfa()){
		vis[t]=1;
		while(vis[t]){
			memset(vis,0,sizeof(vis));
			maxcurrent+=dfs(s,INT_MAX);
		}
	}
}
inline int up(int x,int y){return 4*( (x-1)*m+y ) ;}
inline int right(int x,int y){return 4*( (x-1)*m+y ) + 1;}
inline int down(int x,int y){return 4*( (x-1)*m+y ) + 2;}
inline int left(int x,int y){return 4*( (x-1)*m+y ) + 3;}
int main(){
    read(n,m);
    s=0;t=1;int ty=1;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
			int st,a=up(i,j),b=right(i,j),c=down(i,j),d=left(i,j);
			ty^=1;
			read(st);
			if(ty==0){
				if(st&1)add(s,a,0,0);
				if(st>>1&1)add(s,b,0,0);
				if(st>>2&1)add(s,c,0,0);
				if(st>>3&1)add(s,d,0,0);
				if(i>1)add(a,down(i-1,j),0,0);
				if(j<m)add(b,left(i,j+1),0,0);
				if(i<n)add(c,up(i+1,j),0,0);
				if(j>1)add(d,right(i,j-1),0,0);
			}
			else{
				if(st&1)add(a,t,0,0);
				if(st>>1&1)add(b,t,0,0);
				if(st>>2&1)add(c,t,0,0);
				if(st>>3&1)add(d,t,0,0);
			}
			should+=__builtin_popcount(st);
			switch(st){
				case 1:
					add(a,b,1,ty);
					add(a,d,1,ty);
					add(a,c,2,ty);
					break;
				case 2:
					add(b,a,1,ty);
					add(b,c,1,ty);
					add(b,d,2,ty);
					break;
				case 3:
					add(a,c,1,ty);
					add(b,d,1,ty);
					break;
				case 4:
					add(c,b,1,ty);
					add(c,d,1,ty);
					add(c,a,2,ty);
					break;
				case 6:
					add(b,d,1,ty);
					add(c,a,1,ty);
					break;
				case 7:
					add(c,d,1,ty);
					add(a,d,1,ty);
					add(b,d,2,ty);
					break;
				case 8:
					add(d,a,1,ty);
					add(d,c,1,ty);
					add(d,b,2,ty);
					break;
				case 9:
					add(a,c,1,ty);
					add(d,b,1,ty);
					break;
				case 11:
					add(b,c,1,ty);
					add(d,c,1,ty);
					add(a,c,2,ty);
					break;
				case 12:
					add(d,b,1,ty);
					add(c,a,1,ty);
					break;
				case 13:
					add(a,b,1,ty);
					add(c,b,1,ty);
					add(d,b,2,ty);
					break;
				case 14:
					add(d,a,1,ty);
					add(b,a,1,ty);
					add(c,a,2,ty);
					break;
			}
        }
    }
    //for(int i=0;i<=left(n,m)+1;i++)for(int j=head[i];j;j=e[j].nx)cerr<<i<<' '<<e[j].to<<endl;
	MCMC();
	printf("%d",maxcurrent*2==should?mincost:-1);
    return 0;
}

错的全都是应该有答案但是输出-1.

2024/6/1 15:47
加载中...