zoukankan      html  css  js  c++  java
  • [国家集训队]飞飞侠

    暴力枚举跑三遍堆优化Dijkstra即可

    手写堆记得清零

    #include"cstdio"
    #include"cstring"
    #include"iostream"
    #include"algorithm"
    using namespace std;
    
    const int MAXN=155;
    const char ch[4]={0,'X','Y','Z'};
    const int dx[4]={0,2,3,1},dy[4]={0,3,1,2};
    
    int n,m,siz,tans;
    int x[4],y[4];
    int v[MAXN][MAXN],t[MAXN][MAXN],ln[MAXN][MAXN],id[MAXN][MAXN];
    int ans[4][4];
    struct rpg{
    	int x,y;
    }hp[MAXN*MAXN];
    
    void up(int x)
    {
    	for(int i=x,j=i>>1;j;i=j,j>>=1){
    		if(ln[hp[j].x][hp[j].y]>ln[hp[i].x][hp[i].y]) swap(hp[i],hp[j]),swap(id[hp[i].x][hp[i].y],id[hp[j].x][hp[j].y]);
    		else break;
    	}return;
    }
    
    void ins(rpg x)
    {
    	hp[++siz]=x;
    	id[x.x][x.y]=siz;
    	up(siz);
    	return;
    }
    
    void pop()
    {
    	id[hp[1].x][hp[1].y]=0;
    	hp[1]=hp[siz--];
    	id[hp[1].x][hp[1].y]=1;
    	for(int i=1,j=2;j<=siz;i=j,j<<=1){
    		if(j<siz&&ln[hp[j+1].x][hp[j+1].y]<ln[hp[j].x][hp[j].y]) ++j;
    		if(ln[hp[i].x][hp[i].y]>ln[hp[j].x][hp[j].y]) swap(hp[i],hp[j]),swap(id[hp[i].x][hp[i].y],id[hp[j].x][hp[j].y]);
    		else break;
    	}return;
    }
    
    void Dijkstra(rpg s)
    {
    	memset(ln,0x3f,sizeof(ln));
    	memset(hp,0,sizeof(hp));
    	memset(id,0,sizeof(id));
    	ln[s.x][s.y]=0;ins(s);
    	while(siz){
    		rpg nw=hp[1];pop();
    		int dn=min(n,nw.x+t[nw.x][nw.y]),dm=min(m,nw.y+t[nw.x][nw.y]);
    		for(int i=max(nw.x-t[nw.x][nw.y],1);i<=dn;++i){
    			for(int j=max(nw.y-t[nw.x][nw.y],1);j<=dm;++j){
    				if(abs(nw.x-i)+abs(nw.y-j)>t[nw.x][nw.y]) continue;
    				if(ln[i][j]<=ln[nw.x][nw.y]+v[nw.x][nw.y]) continue;
    				ln[i][j]=ln[nw.x][nw.y]+v[nw.x][nw.y];
    				if(id[i][j]) up(id[i][j]);
    				else ins((rpg){i,j});
    			}
    		}
    	}return;
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=m;++j){
    			scanf("%d",&t[i][j]);
    		}
    	}for(int i=1;i<=n;++i){
    		for(int j=1;j<=m;++j){
    			scanf("%d",&v[i][j]);
    		}
    	}for(int i=1;i<=3;++i) scanf("%d%d",&x[i],&y[i]);
    	for(int i=1;i<=3;++i){
    		Dijkstra((rpg){x[i],y[i]});
    		for(int j=1;j<=3;++j) ans[i][j]=ln[x[j]][y[j]];
    	}tans=min(ans[1][2]+ans[3][2],min(ans[1][3]+ans[2][3],ans[2][1]+ans[3][1]));
    	if(tans>1e9) puts("NO");
    	else{
    		for(int i=1;i<=3;++i){
    			if(ans[dx[i]][i]+ans[dy[i]][i]==tans){
    				printf("%c
    %d
    ",ch[i],tans);
    				return 0;
    			}
    		}
    	}return 0;
    }
    
  • 相关阅读:
    49. Group Anagrams
    43. Multiply Strings
    22. Generate Parentheses
    17. Letter Combinations of a Phone Number
    8. String to Integer (atoi)
    【转】C#中base关键字的几种用法:base()
    【转】C#中virtual和abstract的区别
    [转]C#中的abstract 类和方法
    【转】C#虚方法virtual详解
    【转】C#中protected用法详解
  • 原文地址:https://www.cnblogs.com/AH2002/p/10055519.html
Copyright © 2011-2022 走看看