• [清华集训2017]无限之环(infinityloop)


    description

    题面

    solution

    一开始的思路是插头(DP),然而复杂度太高
    考虑将网格图黑白染色后跑费用流
    流量为接口数,费用为操作次数
    把一个方格拆成五个点,如何连边请自行脑补
    打个表感觉还是挺好写的

    code

    #include<bits/stdc++.h>
    #include<algorithm>
    #include<iostream>
    #include<fstream>
    #include<cstdlib>
    #include<iomanip>
    #include<cstring>
    #include<complex>
    #include<clocale>
    #include<cctype>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<ctime>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<list>
    #include<map>
    #include<set>
    #define FILE "a"
    #define mp make_pair
    #define pb push_back
    #define RG register
    #define il inline
    //#define RAND
    using namespace std;
    typedef unsigned long long ull;
    typedef vector<int>VI;
    typedef long long ll;
    typedef double dd;
    const int inf=2147483647;
    const dd pi=acos(-1);
    const dd eps=1e-10;
    const int mod=1e9+7;
    const int N=100010;
    const ll INF=1e18+1;
    il ll read(){
    	RG ll data=0,w=1;RG char ch=getchar();
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
    	return data*w;
    }
    il int make(int l,int r){return rand()%(r-l+1)+l;}
    il void file(){	
    #ifdef RAND
    	freopen("seed.in","r",stdin);
    	RG int seed=read();fclose(stdin);
    	srand(time(NULL)+seed);
    	freopen("seed.out","w",stdout);
    	seed=rand();printf("%d
    ",seed);
    	fclose(stdout);	
    	freopen(FILE".in","w",stdout);
    #endif
    #ifndef RAND
    	freopen(FILE".in","r",stdin);
    	freopen(FILE".out","w",stdout);
    #endif
    }
    /*********************************************************************/
    
    int n,m,sum[2],p[2000][2000][4];
    int w[]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
    int t[]={0,1,1,3,1,2,3,4,1,3,2,4,3,4,4,5};
    int dy[]={0,1,0,-1},dx[]={-1,0,1,0};
    int S,T,tot,head[N],nxt[N<<1],to[N<<1],val[N<<1],cost[N<<1],cnt=1;
    il void add(int u,int v,int w,int f,bool q){
    	if(q)swap(u,v);if(!w)return;
    	to[++cnt]=v;
    	nxt[cnt]=head[u];
    	val[cnt]=w;
    	cost[cnt]=f;
    	head[u]=cnt;
    	
    	to[++cnt]=u;
    	nxt[cnt]=head[v];
    	val[cnt]=0;
    	cost[cnt]=-f;
    	head[v]=cnt;
    }
    
    queue<int>Q;int dis[N],pn[N],pe[N];bool vis[N];
    il bool spfa(){
    	for(RG int i=1;i<=tot;i++)
    		dis[i]=inf,vis[i]=pn[i]=pe[i]=0;
    	while(!Q.empty())Q.pop();
    	Q.push(S);vis[S]=1;dis[S]=0;
    	while(!Q.empty()){
    		RG int u=Q.front();Q.pop();
    		for(RG int i=head[u];i;i=nxt[i]){
    			RG int v=to[i];
    			if(val[i]&&dis[v]>dis[u]+cost[i]){
    				dis[v]=dis[u]+cost[i];
    				pn[v]=u;pe[v]=i;
    				if(!vis[v]){Q.push(v);vis[v]=1;}
    			}
    		}
    		vis[u]=0;
    	}
    	return dis[T]!=inf;
    }
    
    il int solve(){
    	if(sum[0]!=sum[1])return -1;
    	RG int ans=0,ret=0,power;
    	while(spfa()){
    		power=inf;
    		for(RG int i=T;i!=S;i=pn[i])power=min(power,val[pe[i]]);
    		for(RG int i=T;i!=S;i=pn[i])
    			val[pe[i]]-=power,val[pe[i]^1]+=power;
    		ret+=power;ans+=power*dis[T];
    	}
    	return ret==sum[0]?ans:-1;
    }
    
    int main()
    {
    	n=read();m=read();S=++tot;T=++tot;
    	for(RG int i=1;i<=n;i++)
    		for(RG int j=1;j<=m;j++){
    			for(RG int k=0;k<=4;k++)
    				p[i][j][k]=++tot;
    			RG int s=read(),q=((i+j)&1);sum[q]+=w[s];
    			add(q?T:S,p[i][j][4],w[s],0,q);
    			if(t[s]==1){
    				for(RG int k=0;k<=3;k++)
    					if(s&(1<<k))add(p[i][j][4],p[i][j][k],1,0,q);
    					else if(s&(1<<(k^2)))add(p[i][j][k^2],p[i][j][k],1,2,q);
    					else if(s&(1<<(k^1)))add(p[i][j][k^1],p[i][j][k],1,1,q);
    					else add(p[i][j][k^3],p[i][j][k],1,1,q);
    			}
    			else if(t[s]==2){
    				for(RG int k=0;k<=3;k++)
    					if(s&(1<<k))add(p[i][j][4],p[i][j][k],1,0,q);
    			}
    			else if(t[s]==3){
    				for(RG int k=0;k<=3;k++)
    					if(s&(1<<k))add(p[i][j][4],p[i][j][k],1,0,q);
    					else add(p[i][j][k^2],p[i][j][k],1,1,q);
    			}
    			else if(t[s]==4){
    				for(RG int k=0;k<=3;k++)
    					if(s&(1<<k))add(p[i][j][4],p[i][j][k],1,0,q);
    					else{
    						add(p[i][j][k^1],p[i][j][k],1,1,q);
    						add(p[i][j][k^2],p[i][j][k],1,2,q);
    						add(p[i][j][k^3],p[i][j][k],1,1,q);						
    					}
    			}
    			else if(t[s]==5){
    				for(RG int k=0;k<=3;k++)
    					add(p[i][j][4],p[i][j][k],1,0,q);
    			}
    		}
    	for(RG int i=1;i<=n;i++)
    		for(RG int j=1;j<=m;j++)
    			if((i+j)&1)
    				for(RG int k=0;k<=3;k++){
    					RG int x=i+dx[k],y=j+dy[k];
    					if(x>0&&y>0&&x<=n&&y<=m)
    						add(p[i][j][k],p[x][y][k^2],1,0,(i+j)&1);
    				}	
    	printf("%d
    ",solve());
    	return 0;
    }
    
    
  • 相关阅读:
    摄像头bug查找工作总结
    高通camera结构(摄像头基础介绍)
    什么是滤波器,滤波器是干嘛用的,IIR和FIR滤波器又是什么?(回答请简洁,别浪费大家时间)
    详解摄像头各个引脚的作用关系
    Camera帧率和AE的关系
    CMOS Sensor的调试经验分享
    VSYNC与HSYNC与PCLK与什么有关系
    PCLK怎么获得?
    高清摄像头MIPI接口与ARM处理器的连接
    常用正则
  • 原文地址:https://www.cnblogs.com/cjfdf/p/9457761.html
Copyright © 2020-2023  润新知