⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 guards-v2.c

📁 PASCAL光盘资料PASCAL光盘资料PASCAL光盘资料
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAXN 257#define DEBUG 0typedef struct { int x,y,twin,matched; } thrana; // edgeint M,N; // rows and colsint i,j; // temporaryint R,C; // number of row/col segmentsint A[MAXN][MAXN]; // original mapint BR[MAXN][MAXN],BC[MAXN][MAXN]; // row/col segmentsint Coord[MAXN*MAXN*2]; // row/col of a segmentint V[MAXN*MAXN*2]; // vertex indices in edge arrayint Ma[MAXN*MAXN*2]; // matched vertex?thrana E[MAXN*MAXN]; // edgesint EC; // edge countint from[MAXN*MAXN*2]; // where did i come from?int count=0; // guard countint finish,kde,ec;int mycmp(const void *a, const void *b){	thrana *aa,*bb;	aa=(thrana *)a; bb=(thrana *)b;	if ((aa->x)!=(bb->x)) return ((aa->x)-(bb->x));	return ((aa->y)-(bb->y));}int FindPath(void){	int seen[MAXN*MAXN*2]; // seen a vertex?	int Q[MAXN*MAXN*2]; // queue	int qs,qf; // queue start/finish	int i,kde,kam;	bzero(seen,sizeof(seen));	qs=qf=0;	for (i=0;i<R;i++) if (!Ma[i]) {		from[i]=-1; Q[qf++]=i; seen[i]=1;	}	while (qf>qs) {		kde=Q[qs++];		if (kde<R) {			// follow an unmatched edge			for (i=V[kde];i<V[kde+1];i++) if (!E[i].matched) {				kam=E[i].y;				if (!seen[kam]) { Q[qf++]=kam; seen[kam]=1; from[kam]=kde; }				if (!Ma[kam]) { finish=kam; return 1; }			}		} else {			// follow a matched edge			for (i=V[kde];i<V[kde+1];i++) if (E[i].matched) {				kam=E[i].y;				if (!seen[kam]) { Q[qf++]=kam; seen[kam]=1; from[kam]=kde; }			}		}	}	return 0;}int EdgeNo(int x, int y) {  thrana pom,*p2;		pom.x=y; pom.y=x; pom.twin=0;	p2=(thrana *)bsearch(&pom,E,EC,sizeof(thrana),mycmp);	if (p2==NULL) return -1;	return (p2-E);}int main(void){  FILE *f;  f=fopen("guards.in","r"); stdin=f;  f=fopen("guards.out","w"); stdout=f;	scanf("%d %d ",&M,&N);	for (i=1;i<=M;i++) for (j=1;j<=N;j++) scanf("%d",&A[i][j]);  for (i=0;i<=M+1;i++) { A[i][0]=A[i][N+1]=2; }  for (j=0;j<=N+1;j++) { A[0][j]=A[M+1][j]=2; }	for (i=0;i<=M+1;i++) for (j=0;j<=N+1;j++) BR[i][j]=BC[i][j]=A[i][j];    R=C=0;if (DEBUG){fprintf(stderr,"Input:\n");for(i=1;i<=M;i++){for(j=1;j<=N;j++)fprintf(stderr,"%d ",A[i][j]);fprintf(stderr,"\n");}}	for (i=1;i<=M;i++) { // numbers the rows		j=0; 		while (BR[i][j]==2) j++;		while (j<=N) {			while (BR[i][j]!=2) { BR[i][j]=-R; j++; }			Coord[R]=i;			R++;		  while ((j<=N)&&(BR[i][j]==2)) j++;		}	}if (DEBUG){fprintf(stderr,"Rows:\n");for(i=1;i<=M;i++){	for(j=1;j<=N;j++) fprintf(stderr,"%d ",BR[i][j]); fprintf(stderr,"\n");}}	  for (j=1;j<=N;j++) { // numbers the cols		i=0; 		while (BC[i][j]==2) i++;		while (i<=M) {			while (BC[i][j]!=2) { BC[i][j]=-C; i++; }			Coord[R+C]=j;			C++; // :-)) C++ rulez		  while ((i<=M)&&(BC[i][j]==2)) i++;		}	}if (DEBUG){fprintf(stderr,"Cols:\n");for(i=1;i<=M;i++){	for(j=1;j<=N;j++)fprintf(stderr,"%d ",BC[i][j]); fprintf(stderr,"\n");}}	  	// build the graph	EC=0;	for (i=1;i<=M;i++) for (j=1;j<=N;j++) if (A[i][j]==0) {		E[EC].x=-BR[i][j]; E[EC].y=R-BC[i][j]; 		E[EC].twin=-1; E[EC].matched=0; EC++;		E[EC].x=R-BC[i][j]; E[EC].y=-BR[i][j];		E[EC].twin=-1; E[EC].matched=0; EC++;  }	qsort(E,EC,sizeof(thrana),mycmp);	E[EC].x=E[EC].y=R+C+47;if (DEBUG){fprintf(stderr,"Edges:\n");for (i=0;i<EC;i++) fprintf(stderr,"[%d %d] ",E[i].x,E[i].y); fprintf(stderr,"\n");}	  for (i=0;i<R+C;i++) V[i]=-1;  i=j=0;	while (j<EC) {		if (E[j].x>=i) { V[i]=j; i++; } else j++;	}	V[R+C]=EC;if (DEBUG){fprintf(stderr,"Vertices start:\n");for (i=0;i<R+C;i++) fprintf(stderr,"%d ",V[i]); fprintf(stderr,"\n");}  for (i=0;i<EC;i++) if (E[i].twin==-1) 		E[i].twin=EdgeNo(E[i].x,E[i].y); if (DEBUG){fprintf(stderr,"Twins:\n");for (i=0;i<R+C;i++) fprintf(stderr,"%d ",E[i].twin); fprintf(stderr,"\n");}  // find maximum matching  for (i=0;i<R+C;i++) Ma[i]=0;  while (FindPath()){		count++;		// switch the edges along the path		kde=finish;		Ma[kde]=1;		while (from[kde]!=-1) { 			ec=EdgeNo(kde,from[kde]);			E[ec].matched=1-E[ec].matched; 			E[E[ec].twin].matched=1-E[E[ec].twin].matched;			kde=from[kde]; 			if (kde!=-1) Ma[kde]=1;		}	}	printf("%d\n",count);  for (i=0;i<EC;i++) 		if ((E[i].matched)&&(E[i].x<E[i].y)) 			printf("%d %d\n",Coord[E[i].x],Coord[E[i].y]);  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -