zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    P1217 [USACO1.5]回文质数 Prime Palindromes
    C++ 队列(queue)堆栈(stack)实现基础
    深入理解指针—>指针函数与函数指针的区别
    C语言结构体及typedef关键字定义结构体别名和函数指针的应用
    实现常用的配置文件/初始化文件读取的一个C程序
    C语言sscanf和sprintf输入输出使用及Strlen、Memset解释
    C语言一些基础知识
    Google的开源C++单元测试框架Google Test
    网站(Web)压测工具Webbench源码分析
    web压测工具http_load原理分析
  • 原文地址:https://www.cnblogs.com/silenty/p/9790829.html
Copyright © 2011-2022 走看看