BZOJ 2595: [Wc2008]游览计划

来源:互联网 发布:淘宝买家秀怎么发微淘 编辑:程序博客网 时间:2024/05/01 03:34

啊 斯坦纳树 好像很厉害啊 反正我之前不会。。。
其实不知道实用性怎么样 毕竟复杂度不小。。。
大概过程就是一个状压DP+spfa 枚举状态 从小状态更新大状态 再对当前状态做一次像spfa一样的松弛操作

下面这个人讲的不错 可以去看看
http://blog.csdn.net/gzh1992n/article/details/9119543
为什么我的代码又那么短 有点担心优美度了 有谁提一下建议吗2333 我觉得还过得去?

#include<bits/stdc++.h>#define me(a,x) memset(a,x,sizeof a)using namespace std;const int N=11,inf=1e9+7;const int dx[4]={0,0,1,-1};const int dy[4]={1,-1,0,0};inline int read(){    char ch=getchar(); int x=0,f=1;    while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0'; ch=getchar();}    return x*f;}struct S{int x,y,k;}g[N][N][1030];int f[N][N][1030],a[N][N],n,m,b[N][N],cnt;bool v[N][N];bool upd(int x,int y,int u,int i,int j,int k,int w){    if(f[x][y][u]>w)return f[x][y][u]=w,g[x][y][u]=(S){i,j,k},1;    return 0;}queue<S>q;void spfa(int t){    while(!q.empty()){        S u=q.front(); q.pop();        v[u.x][u.y]=0;        for(int k=0;k<4;k++){            int x=u.x+dx[k],y=u.y+dy[k];            if(x<1 || y<1 || x>n || y>m)continue;            if(upd(x,y,t,u.x,u.y,t,f[u.x][u.y][t]+a[x][y]) && !v[x][y])                v[x][y]=1,q.push((S){x,y,t});        }    }}void dfs(int x,int y,int k){    if(!k)return; v[x][y]=1;    dfs(g[x][y][k].x,g[x][y][k].y,g[x][y][k].k);    if(x==g[x][y][k].x && y==g[x][y][k].y)dfs(x,y,k-g[x][y][k].k);}void op(){    for(int i=1;i<=n;i++){        for(int j=1;j<=m;j++){            if(!a[i][j])printf("x");            else if(v[i][j])printf("o");            else printf("_");        }        printf("\n");    }}int main(){    n=read(),m=read(); me(f,63);    int i,j,k,s; cnt=0;    for(i=1;i<=n;i++)for(j=1;j<=m;j++){        a[i][j]=read();        if(!a[i][j]){            b[i][j]=1<<cnt,f[i][j][1<<cnt]=0;            cnt++; g[i][j][1<<cnt].k=0;        }        f[i][j][0]=a[i][j];    }    int p=(1<<cnt);    for(k=1;k<p;k++){        me(v,0);        for(i=1;i<=n;i++)for(j=1;j<=m;j++){            if(!a[i][j] && !(k&b[i][j]))continue;            for(s=k;s;s=(s-1)&k)                upd(i,j,k,i,j,s,f[i][j][s]+f[i][j][k-s]-a[i][j]);            if(f[i][j][k]<inf)q.push((S){i,j,k}),v[i][j]=1;        }        spfa(k);    }    for(i=1;i<=n;i++)for(j=1;j<=m;j++)if(!a[i][j]){        printf("%d\n",f[i][j][p-1]);        me(v,0); dfs(i,j,p-1);        op();        return 0;    }}
1 0
原创粉丝点击