google code jam 2014 RB_C

求割来计算最大流,问题求补,条件是对偶问题的不对称性,形象来说,就是已知棋盘格子数,大部分都是棋子,求棋子个数,当然数空格数,就是这个道理。

#include <cstdio>
#include <queue>
#include <vector>
using namespace std;


#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define INF 0x7fffffff

int abs(int a){
	return a>0?a:-a;
}
int T,W,H,B,x[2004],y[2004];
int edge[2][1002][1002],edge2[1002][1002];
int dis[1002];
bool vis[1002];


int main(){
	freopen("C-large-practice .in","r",stdin);
	freopen("out2","w",stdout);
	scanf("%d",&T);
	for(int cas=1; cas<=T; ++cas){
		scanf("%d%d%d",&W,&H,&B);
		for(int i=0; i<2*B; i+=2){
			scanf("%d%d%d%d",x+i,y+i,x+i+1,y+i+1);
		}
		x[2*B]=-1; y[2*B]=0; x[2*B+1]=-1; y[2*B+1]=H-1;
		x[2*B+2]=x[2*B+3]=W; y[2*B+2]=0; y[2*B+3]=H-1;
		for(int i=0; i<B+2; ++i){
			for(int j=0; j<B+2; ++j){
				if(i==j) continue;
				if(x[2*i]>=x[2*j]-1&&x[2*i]<=x[2*j+1]+1) edge[0][i][j]=edge[0][j][i]=0;
				else if(x[2*i+1]>=x[2*j]-1&&x[2*i+1]<=x[2*j+1]+1) edge[0][i][j]=edge[0][j][i]=0;
				else{
					edge[0][i][j]=edge[0][j][i]=min(abs(x[2*j+1]-x[2*i]),abs(x[2*i+1]-x[2*j]));
					edge[0][i][j]--;
				}
				
				if(y[2*i]>=y[2*j]-1&&y[2*i]<=y[2*j+1]+1) edge[1][i][j]=edge[1][j][i]=0;
				else if(y[2*i+1]>=y[2*j]-1&&y[2*i+1]<=y[2*j+1]+1) edge[1][i][j]=edge[1][j][i]=0;
				else{
					edge[1][i][j]=edge[1][j][i]=min(abs(y[2*j+1]-y[2*i]),abs(y[2*i+1]-y[2*j]));
					edge[1][i][j]--;
				}
				
				edge2[i][j]=max(edge[0][i][j],edge[1][i][j]);
			}
		}
		for(int i=0; i<B+2; ++i)
			for(int j=0; j<B+2; ++j)
				edge2[i][j]=min(edge2[i][j],edge2[j][i]);
		
		for(int i=0; i<B+2; ++i) dis[i]=INF,vis[i]=false;
		dis[B]=0;
		priority_queue<pair<int,int> > q;
		q.push(make_pair(0,B)); 
		while(q.empty()==false){
			pair<int,int> tmp=q.top();
			if(tmp.second==B+1) break;
			vis[tmp.second]=true;
			q.pop();
			for(int i=0; i<B+2; ++i){
				if(vis[i]) continue;
				if(-tmp.first+edge2[i][tmp.second]<dis[i]){
					q.push(make_pair(tmp.first-edge2[i][tmp.second],i));
					dis[i]=-tmp.first+edge2[i][tmp.second];
				}
			}
		}
		printf("Case #%d: %d\n",cas,dis[B+1]);
	}
}


你可能感兴趣的:(google code jam 2014 RB_C)