google code jam 2014 RB_C

来源:互联网 发布:淘宝售后客服的重要性 编辑:程序博客网 时间:2024/05/17 06:19

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

#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 0x7fffffffint 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]);}}


0 0