CodeForces 152E

来源:互联网 发布:java 变量类型 编辑:程序博客网 时间:2024/06/14 02:43

斯坦纳树+输出方案

#include<cstdio>#include<iostream>#include<cstring>const int N=210;const int INF=1e9;int tot;int g[N][N];int mp[N][N];int val[N];int mi[N][N];void flody(){    memset(mi,-1,sizeof(mi));    for(int k=0;k<tot;k++){        for(int i=0;i<tot;i++){            for(int j=0;j<tot;j++){                //g[i][j]=min(g[i][j],g[i][k]+g[k][j]-val[k]);                if(g[i][k]+g[k][j]-val[k]<g[i][j]){                    g[i][j]=g[i][k]+g[k][j]-val[k];                    mi[i][j]=k;                }            }        }    }}int vis[N];int s[N];int dp[N][1<<7];int pre[N][1<<7][2];int n,m,K;void stn(){    int cnt=0;    for(int i=0;i<tot;i++){        if(vis[i]){            //printf("%d %d\n",i/m+1,i%m+1);            s[i]=1<<cnt;            cnt++;        }        else s[i]=0;    }    memset(dp,0x3f,sizeof(dp));    for(int i=0;i<tot;i++){        dp[i][s[i]]=val[i];    }    memset(pre,-1,sizeof(pre));    int ed=1<<cnt;    for(int i=1;i<ed;i++){        for(int j=0;j<tot;j++){            for(int k=(i-1)&i;k;k=(k-1)&i){                //dp[j][i]=min(dp[j][i],dp[j][k|s[j]]+dp[j][i^k|s[j]]-val[j]);                int x=dp[j][k|s[j]],y=dp[j][i^k|s[j]];                if(dp[j][i]>x+y-val[j]){                    dp[j][i]=x+y-val[j];                    pre[j][i][0]=j;                    pre[j][i][1]=k|s[j];                }            }        }        for(int j=0;j<tot;j++){            for(int j1=0;j1<tot;j1++){                //dp[j1][i|s[j1]]=min(dp[j1][i|s[j1]],dp[j][i]+val[j1]);                if(dp[j][i]+g[j][j1]-val[j]<dp[j1][i|s[j1]]){                    dp[j1][i|s[j1]]=dp[j][i]+g[j][j1]-val[j];                    pre[j1][i|s[j1]][0]=j;                    pre[j1][i|s[j1]][1]=i;                }            }        }    }}int aa[N][N];int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};int check(int i,int j){    if(i<1||i>n||j<1||j>m)return 0;    return 1;}int ans[N][N];void _find(int x,int y){    int m1=mi[x][y];    ans[x/m+1][x%m+1]=1;    ans[y/m+1][y%m+1]=1;    if(m1!=-1){        _find(x,m1);        _find(m1,y);    }}void dfs(int id,int st){    int x=pre[id][st][0],y=pre[id][st][1];    ans[id/m+1][id%m+1]=1;    if(x==-1)return ;    if(x==id){        dfs(x,y|s[id]);        dfs(x,st^y|s[id]);    }    else {        _find(x,id);        dfs(x,y);    }}int main(){    #ifdef DouBi    freopen("in.cpp","r",stdin);    #endif // DouBi    while(scanf("%d%d%d",&n,&m,&K)!=EOF){        tot=0;        for(int i=1;i<=n;i++){            for(int j=1;j<=m;j++){                mp[i][j]=tot;                scanf("%d",&val[tot++]);            }        }        memset(g,0x3f,sizeof(g));        for(int i=1;i<=n;i++){            for(int j=1;j<=m;j++){                g[mp[i][j]][mp[i][j]]=val[mp[i][j]];            }        }        for(int i=1;i<=n;i++){            for(int j=1;j<=m;j++){                for(int k=0;k<4;k++){                    int ii=i+dir[k][0],jj=j+dir[k][1];                    if(check(ii,jj)){                        g[mp[i][j]][mp[ii][jj]]=val[mp[i][j]]+val[mp[ii][jj]];                    }                }            }        }        flody();//        for(int i=0;i<tot;i++){//            for(int j=0;j<tot;j++){//                printf("%d ",g[i][j]);//            }printf("\n");//        }        memset(vis,0,sizeof(vis));        for(int i=0;i<K;i++){            int a,b;scanf("%d%d",&a,&b);            vis[mp[a][b]]=1;        }        stn();        int ed=1<<K;        int id=-1,ans1=INF;        for(int i=0;i<tot;i++){            if(dp[i][ed-1]<ans1){                ans1=dp[i][ed-1];                id=i;            }        }        printf("%d\n",ans1);        memset(ans,0,sizeof(ans));        dfs(id,ed-1);        for(int i=1;i<=n;i++){            for(int j=1;j<=m;j++){                printf("%c",ans[i][j]?'X':'.');            }printf("\n");        }    }    return 0;}
0 0
原创粉丝点击