• BZOJ 2595: [Wc2008]游览计划


    斯坦纳树

    Dijkstra+堆貌似慢了一倍

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int n,m,lim=1,F[12][12][1050],a[12][12],vis[12][12],instack[12][12];
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    struct node{
    	int x,y,sta;
    }Pre[12][12][1050],q[1000005];
    void spfa(int now){
    //	printf("ans:%d
    ",now);
    	int head=0,tail=1;
    	memset(instack,0,sizeof(instack));
    	for (int i=1; i<=n; i++)
    		for (int j=1; j<=m; j++){
    			q[++tail]=(node){i,j,0};
    			instack[i][j]=1;
    		}
    	while (head<tail){
    		head++;
    		int x=q[head].x,y=q[head].y;
    		instack[x][y]=0;
    		for (int i=0; i<4; i++){
    			int fx=x+dx[i],fy=y+dy[i];
    			if (fx<1 || fx>n || fy<1 || fy>m) continue;
    			if (F[fx][fy][now]>F[x][y][now]+a[fx][fy]){
    				F[fx][fy][now]=F[x][y][now]+a[fx][fy];
    				Pre[fx][fy][now]=(node){x,y,now};
    				if (!instack[fx][fy]){
    					instack[fx][fy]=1;
    					q[++tail]=(node){fx,fy,0};
    				}
    			}
    		}
    	}
    }
    void solve(int x,int y,int now){
    	if (!now) return;
    	int X=Pre[x][y][now].x,Y=Pre[x][y][now].y,sta=Pre[x][y][now].sta;
    	solve(X,Y,sta);
    	if (X==x && Y==y){
    		if (sta) solve(X,Y,now-sta);
    	}
    	else vis[x][y]=1;
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for (int i=1; i<=n; i++)
    		for (int j=1; j<=m; j++){
    			scanf("%d",&a[i][j]);
    			if (a[i][j]==0) lim<<=1;
    		}
    	for (int i=1; i<=n; i++)
    		for (int j=1; j<=m; j++)
    			for (int now=1; now<lim; now++)
    				F[i][j][now]=1e9;
    	int num=0;
    	for (int i=1; i<=n; i++)
    		for (int j=1; j<=m; j++)
    			if (!a[i][j]) {
    				F[i][j][1<<num]=0;
    				num++;
    			}
    	for (int now=1; now<lim; now++){
    		for (int i=1; i<=n; i++)
    			for (int j=1; j<=m; j++)
    				for (int sta=now; sta; sta=((sta-1)&now)){
    					if (F[i][j][now]>F[i][j][sta]+F[i][j][now-sta]-a[i][j]){
    						F[i][j][now]=F[i][j][sta]+F[i][j][now-sta]-a[i][j];
    						Pre[i][j][now]=(node){i,j,sta};
    					}
    				}
    		spfa(now);
    	}
    	int ansx=0,ansy=0;
    	for (int i=1; i<=n; i++)
    		for (int j=1; j<=m; j++)
    			if (!a[i][j]){
    				ansx=i,ansy=j;
    				break;	
    			}
    	solve(ansx,ansy,lim-1);
    	printf("%d
    ",F[ansx][ansy][lim-1]);
    	for (int i=1; i<=n; i++){
    		for (int j=1; j<=m; j++)
    			if (!a[i][j]) printf("x");
    			else if (vis[i][j]) printf("o");
    			else printf("_");
    		printf("
    ");
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    centos下tomcat自启动
    navcat12 windows 下载安装
    mysql8 windows 下载安装
    redis windows下载安装
    python json.dumps()函数输出json格式,使用indent参数对json数据格式化输出
    Python的安装图解
    spark入门系列教程二——简单入门实例
    Spark入门系列教程一 —— Spark2.3.1 集群安装
    css在文字两边加线,文字居中效果——实战应用
    a标签中对于邮箱和电话的用法mark
  • 原文地址:https://www.cnblogs.com/silenty/p/9790829.html
Copyright © 2020-2023  润新知