zoukankan      html  css  js  c++  java
  • [BZOJ4823][CQOI2017]老C的方块

    bzoj
    luogu

    Description

    老C是个程序员。
    作为一个懒惰的程序员,老C经常在电脑上玩方块游戏消磨时间。游戏被限定在一个由小方格排成的R行C列网格上,如果两个小方格有公共的边,就称它们是相邻的,而且有些相邻的小方格之间的公共边比较特殊。特殊的公共边排列得有很强的规律。首先规定,第1行的前两个小方格之间的边是特殊边。然后,特殊边在水平方向上每4个小方格为一个周期,在竖直方向上每2个小方格为一个周期。所有的奇数列与下一列之间都有特殊边,且所在行的编号从左到右奇偶交替。
    下图所示是一个R=C=8的网格,蓝色标注的边是特殊边。首先,在第1行,第1列和第2列之间有一条特殊边。因为竖直方向周期为2,所以所有的奇数行,第1列和第2列之间都有特殊边。因为水平方向周期为4,所以所有奇数行的第5列和第6列之间也有特殊边,如果网格足够大,所有奇数行的第9列和第10列、第13列和第14列之间都有特殊边。因为所有的奇数列和下一列之间都有特殊边,所以第3列和第4列、第7列和第8列之间也有特殊边,而所在行的编号从左到右奇偶交替,所以它们的特殊边在偶数行。如果网格的规模更大,我们可以用同样的方法找出所有的特殊边。

    网格的每个小方格刚好可以放入一个小方块,在游戏的一开始,有些小方格已经放上了小方块,另外的小方格没有放。老C很讨厌下图所示的图形,如果他发现有一些小方块排列成了它讨厌的形状(特殊边的位置也要如图中所示),就很容易弃疗,即使是经过任意次旋转、翻转后排列成讨厌的形状,老C也同样容易弃疗。

    为了防止弃疗,老C决定趁自己还没有弃疗,赶紧移除一些格子里小方块,使得剩下的小方块不能构成它讨厌的形状。但是游戏里每移除一个方块都是要花费一些金币的,每个方块需要花费的金币有多有少参差不齐。老C当然希望尽可能少的使用游戏里的金币,但是最少要花费多少金币呢?老C懒得思考,就把这个问题交给你了。

    Input

    第一行有3个正整数C,R,n,表示C列R行的网格中,有n个小方格放了小方块。接下来n行,每行3个正整数x,y,w,表示在第x列第y行的小方格里放了小方块,移除它

    需要花费w个金币。保证不会重复,且都在网格范围内。

    Output

    输出一行,包含一个整数,表示最少花费的金币数量。

    Sample Input 1

    2 2 4
    1 1 5
    1 2 6
    2 1 7
    2 2 8

    Sample Output 1

    5

    Sample Input 2

    3 3 7
    1 1 10
    1 2 15
    1 3 10
    2 1 10
    2 2 10
    2 3 10
    3 1 10

    Sample Output 2

    15

    sol

    这种网格图尝试一下黑白染色?
    染完之后发现这个老C会弃疗的图案没有太大关系啊。
    怎么办呢?我们按照如下方式染色。
    别问我是怎么知道这么染色的
    这样以来,所有会让老C弃疗的图案都会是一条红-黄-蓝-绿的连续路径
    也就是说我们要消灭所有的这种连续路径。
    考虑最小割,按如下方式建图即可。

    坐标范围有点大,可以直接开(map)存。
    至于复杂度...不会证qaq

    code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #include<map>
    using namespace std;
    int gi(){
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    const int N = 1e5+5;
    const int inf = 2e9;
    struct edge{int to,nxt,w;}a[N<<4];
    int n,x[N],y[N],val[N],col[N],S,T,head[N],cnt=1,dep[N],cur[N];
    int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
    map<int,int>M[N];queue<int>Q;
    void link(int u,int v,int w){
    	a[++cnt]=(edge){v,head[u],w};head[u]=cnt;
    	a[++cnt]=(edge){u,head[v],0};head[v]=cnt;
    }
    bool bfs(){
    	memset(dep,0,sizeof(dep));
    	dep[S]=1;Q.push(S);
    	while (!Q.empty()){
    		int u=Q.front();Q.pop();
    		for (int e=head[u];e;e=a[e].nxt)
    			if (a[e].w&&!dep[a[e].to])
    				dep[a[e].to]=dep[u]+1,Q.push(a[e].to);
    	}
    	return dep[T];
    }
    int dfs(int u,int f){
    	if (u==T) return f;
    	for (int &e=cur[u];e;e=a[e].nxt)
    		if (a[e].w&&dep[a[e].to]==dep[u]+1){
    			int tmp=dfs(a[e].to,min(a[e].w,f));
    			if (tmp) {a[e].w-=tmp;a[e^1].w+=tmp;return tmp;}
    		}
    	return 0;
    }
    int dinic(){
    	int res=0;
    	while (bfs()){
    		for (int i=1;i<=T;++i) cur[i]=head[i];
    		while (int tmp=dfs(S,inf)) res+=tmp;
    	}
    	return res;
    }
    void build1(int v){
    	for (int d=0;d<4;++d){
    		int i=x[v]+dx[d],j=y[v]+dy[d],u=M[i][j];
    		if (u)
    			if (col[u]==2) link(v,u,min(val[u],val[v]));
    			else link(u,v,inf);
    	}
    }
    void build2(int u){
    	for (int d=0;d<4;++d){
    		int i=x[u]+dx[d],j=y[u]+dy[d],v=M[i][j];
    		if (v)
    			if (col[v]==1) link(u,v,min(val[u],val[v]));
    			else link(u,v,inf);
    	}
    }
    int main(){
    	gi();gi();n=gi();S=n+1;T=S+1;
    	for (int i=1;i<=n;++i){
    		x[i]=gi(),y[i]=gi(),val[i]=gi();
    		M[x[i]][y[i]]=i;
    		col[i]=(x[i]%4>=2)*2+(((x[i]+y[i])&1)^1);
    	}
    	for (int i=1,j;i<=n;++i)
    		if (col[i]==0) link(S,i,val[i]);
    		else if (col[i]==1) build1(i);
    		else if (col[i]==2) build2(i);
    		else link(i,T,val[i]);
    	printf("%d
    ",dinic());return 0;
    }
    
  • 相关阅读:
    第七章补充 -- 关于文件目录的交互 OS
    第七章 -- 关于文件
    Python 函数声明和调用
    第三章 -- Python的基本数据类型
    关于tomcat控制台乱码
    UTF8MB4 是支持 表情符号的
    ngnix启动不了 解决办法
    关于jmeter 加载jar文件的疑问
    jmeter 使用 随机数据+md5加密注意事项
    jmeter 分布式注意事项
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/9100092.html
Copyright © 2011-2022 走看看