zoukankan      html  css  js  c++  java
  • BZOJ2595: [Wc2008]游览计划

    Description

    Input

    第一行有两个整数,N和 M,描述方块的数目。 
    接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个景点;
    否则表示控制该方块至少需要的志愿者数目。 相邻的整数用 (若干个) 空格隔开,
    行首行末也可能有多余的空格。

    Output


    由 N + 1行组成。第一行为一个整数,表示你所给出的方案
    中安排的志愿者总数目。 
    接下来 N行,每行M 个字符,描述方案中相应方块的情况: 
    z  ‘_’(下划线)表示该方块没有安排志愿者; 
    z  ‘o’(小写英文字母o)表示该方块安排了志愿者; 
    z  ‘x’(小写英文字母x)表示该方块是一个景点; 
    注:请注意输出格式要求,如果缺少某一行或者某一行的字符数目和要求不
    一致(任何一行中,多余的空格都不允许出现) ,都可能导致该测试点不得分。

    Sample Input

    4 4
    0 1 1 0
    2 5 5 1
    1 5 5 1
    0 1 1 0

    Sample Output

    6
    xoox
    ___o
    ___o
    xoox

    HINT

     对于100%的数据,N,M,K≤10,其中K为景点的数目。输入的所有整数均在[0,2^16]的范围内

    求过给定点的最小生成树:斯坦纳树开搞

    考虑DP,有两个DP:dp[i][j] 表示到达i这个点,当前状态为j ,注意第二维是状压,用来表示给定点是否被选

    dp[ i ][ j ]=min{ dp[ i ][ j ],dp[ i ][ k ]+dp[ i ][ l ] }

    dp[ i ][ j ]=min{ dp[ i ][ j ],dp[ i' ][ j ]+cost i to i'}这个用SPFA一起随DP跑

    复杂度很高,O(n*3^k),慎用

    代码如下:

    //MT_LI
    #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<vector> #include<ctime> #include<map> #include<bitset> #include<set> #define ll long long #define mp(x,y) make_pair(x,y) #define pll pair<long long,long long> #define pii pair<int,int> using namespace std; inline int read() { int f=1,x=0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int stack[20]; inline void write(int x) { if(x<0){putchar('-');x=-x;} if(!x){putchar('0');return;} int top=0; while(x)stack[++top]=x%10,x/=10; while(top)putchar(stack[top--]+'0'); } inline void pr1(int x){write(x);putchar(' ');} inline void pr2(int x){write(x);putchar(' ');} int n,m; struct node{ int x,y,next; }a[410];int len,last[110]; void ins(int x,int y){a[++len]=(node){x,y,last[x]};last[x]=len;} int head,tail,list[210];bool v[210]; int pre[110][2100]; int f[110][2100]; int c[110],cnt; int dx[4]={1,0,-1,0}; int dy[4]={0,1,0,-1}; void spfa(int u) { while(head!=tail) { int x=list[head]; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(f[y][u]>f[x][u]+c[y]) { f[y][u]=f[x][u]+c[y]; pre[y][u]=-x; if(v[y]==false) { v[y]=true; list[tail++]=y; if(tail==200)tail=1; } } } head++;if(head==200)head=1; v[x]=false; } } char ss[110]; void dfs(int x,int u) { if(ss[x]!='x')ss[x]='o'; if(pre[x][u]>0) dfs(x,pre[x][u]),dfs(x,u^pre[x][u]); else if(pre[x][u]<0) dfs(-pre[x][u],u); } int main() { n=read(),m=read();cnt=0; len=0;memset(last,0,sizeof(last)); memset(f,63,sizeof(f)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { int pos=(i-1)*m+j; c[pos]=read(); if(c[pos]==0)cnt++,f[pos][1<<(cnt-1)]=0; for(int k=0;k<4;k++) { int edx=i+dx[k],edy=j+dy[k]; if(1<=edx&&edx<=n&&1<=edy&&edy<=m) ins(pos,(edx-1)*m+edy); } } head=1,tail=1; for(int u=1;u<=((1<<cnt)-1);u++) { for(int i=1;i<=n*m;i++) for(int v=((u-1)&u);v;v=((v-1)&u)) if(f[i][u]>f[i][v]+f[i][u^v]-c[i]) { f[i][u]=f[i][v]+f[i][u^v]-c[i]; pre[i][u]=v; } memset(v,false,sizeof(v)); for(int i=1;i<=n*m;i++) if(f[i][u]!=f[0][0]) { v[i]=true; list[tail++]=i; if(tail==200)tail=1; } spfa(u); } int ans=f[0][0],pos; for(int i=1;i<=n*m;i++) if(ans>f[i][(1<<cnt)-1])ans=f[i][(1<<cnt)-1],pos=i; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(c[(i-1)*m+j]==0)ss[(i-1)*m+j]='x'; else ss[(i-1)*m+j]='_'; dfs(pos,(1<<cnt)-1); printf("%d ",ans); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++)printf("%c",ss[(i-1)*m+j]); printf(" "); } return 0; }
  • 相关阅读:
    HDU Railroad (记忆化)
    HDU 1227 Fast Food
    HDU 3008 Warcraft
    asp vbscript 检测客户端浏览器和操作系统(也可以易于升级到ASP.NET)
    Csharp 讀取大文本文件數據到DataTable中,大批量插入到數據庫中
    csharp 在万年历中计算显示农历日子出错
    csharp create ICS file extension
    CSS DIV Shadow
    DataTable search keyword
    User select fontface/color/size/backgroundColor设置 字体,颜色,大小,背景色兼容主流浏览器
  • 原文地址:https://www.cnblogs.com/MT-LI/p/10589041.html
Copyright © 2011-2022 走看看