zoukankan      html  css  js  c++  java
  • 斯坦纳树

    大意: 给定一张图 求图上一个点集的最小生成树。

    考虑状态压缩 状态 dp[i][j] 为 当前走在 点i 状态为j 每一位表示 是否已在生成树中

      于是 spfa 过程可以更新 ->  在每一个节点上均可考虑 移动 或者 与在该点上的其他状态进行合并

    根据题目的描述 可以 微调 dp 过程   为什么我的常数大的可怕 又或者 是写得太残 或是 这题其实可以更妙  总而言之 还是太naive

    bzoj 2595 
      1 #include <bits/stdc++.h>
      2 #define p(i,j) (i-1)*m+j
      3 #define inf 0x3fffffff
      4 using namespace std;
      5 
      6 inline int read()
      7 {
      8     int x=0,f=1;
      9     char ch=getchar();
     10     while(ch<'0'||ch>'9')
     11     {
     12         if(ch=='-')f=-1;
     13         ch=getchar();
     14     }
     15     while(ch>='0'&&ch<='9')
     16     {
     17         x=x*10+ch-'0';
     18         ch=getchar();
     19     }
     20     return x*f;
     21 }
     22 struct edge
     23 {
     24     int u,v,next;
     25 } vs[300000];
     26 struct state
     27 {
     28     int at,mask;
     29 };
     30 int n,m,st[2010],ee,fang[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};
     31 int pl[12],tot,vis[2100][4100],ans=0;
     32 char mmp[12][12];
     33 int dis[2100][4100],pre[2110][4100][2][2],val[2100];
     34 inline void addedge(int u,int v)
     35 {
     36     vs[++ee].v=v;
     37     vs[ee].u=u;
     38     vs[ee].next=st[u];
     39     st[u]=ee;
     40 }
     41 void getpos(int x,char c)
     42 {
     43     int xx=x/m+1,y=(x%m==0)? m:x%m;
     44     if(x%m==0)xx--;
     45     mmp[xx][y]=c;
     46 }
     47 void gethash(state&a,int b)
     48 {
     49     for(int i=1; i<=tot; i++)
     50         if(pl[i]==b)a.mask|=(1<<i-1);
     51 }
     52 void spfa()
     53 {
     54     queue <state> q;
     55     state tmp;
     56     for(int i=1; i<=n*m; i++)
     57     {
     58         tmp.at=i;
     59         tmp.mask=0;
     60         gethash(tmp,i);
     61         q.push(tmp);
     62         dis[tmp.at][tmp.mask]=val[tmp.at];
     63         vis[tmp.at][tmp.mask]=1;
     64     }
     65     while(!q.empty())
     66     {
     67         state lx=q.front();
     68         q.pop();
     69         if(lx.mask==(1<<tot)-1) continue;
     70         //move
     71         for(int i=st[lx.at]; i; i=vs[i].next)
     72         {
     73             tmp.at=vs[i].v;
     74             tmp.mask=lx.mask;
     75             gethash(tmp,vs[i].v);
     76             if(dis[tmp.at][tmp.mask]>dis[lx.at][lx.mask]+val[tmp.at])
     77             {
     78                 dis[tmp.at][tmp.mask]=dis[lx.at][lx.mask]+val[tmp.at];
     79                 pre[tmp.at][tmp.mask][0][0]=lx.at;
     80                 pre[tmp.at][tmp.mask][1][0]=lx.mask;
     81                 pre[tmp.at][tmp.mask][0][1]=0;
     82                 pre[tmp.at][tmp.mask][1][1]=0;
     83                 if(!vis[tmp.at][tmp.mask]) q.push(tmp),vis[tmp.at][tmp.mask]=1;
     84             }
     85         }
     86         //merge
     87         for(int i=1; i<(1<<tot); i++)
     88         {
     89             tmp.at=lx.at;
     90             tmp.mask=lx.mask;
     91             tmp.mask|=i;
     92             if(dis[tmp.at][tmp.mask]>dis[lx.at][lx.mask]+dis[lx.at][i]-val[lx.at])
     93             {
     94                 dis[tmp.at][tmp.mask]=dis[lx.at][lx.mask]+dis[lx.at][i]-val[lx.at];
     95                 pre[tmp.at][tmp.mask][0][0]=lx.at;
     96                 pre[tmp.at][tmp.mask][1][0]=lx.mask;
     97                 pre[tmp.at][tmp.mask][0][1]=lx.at;
     98                 pre[tmp.at][tmp.mask][1][1]=i;
     99                 if(!vis[tmp.at][tmp.mask]) q.push(tmp),vis[tmp.at][tmp.mask]=1;
    100             }
    101         }
    102         vis[lx.at][lx.mask]=0;
    103     }
    104 }
    105 void fillwith(int x1,int x2)
    106 {
    107     if(!x1&&!x2) return ;
    108 //    printf("%d
    ",dis[x1][x2]);
    109     if(val[x1]) getpos(x1,'o');
    110     else getpos(x1,'x');
    111     fillwith(pre[x1][x2][0][0],pre[x1][x2][1][0]);
    112     fillwith(pre[x1][x2][0][1],pre[x1][x2][1][1]);
    113 }
    114 void makeways()
    115 {
    116     int g=0;
    117     for(int i=1; i<=n; i++)
    118         for(int j=1; j<=n; j++)
    119             if(dis[p(i,j)][(1<<tot)-1]<dis[g][(1<<tot)-1])
    120                 g=p(i,j);
    121     cout<<dis[g][(1<<tot)-1]<<endl;
    122     fillwith(g,(1<<tot)-1);
    123 }
    124 int main()
    125 {
    126     for(int i=0; i<=100; i++) for(int k=0; k<=1024; k++) dis[i][k]=inf;
    127     n=read();
    128     m=read();
    129     for(int i=1; i<=n; i++)
    130         for(int j=1; j<=m; j++)
    131         {
    132             val[p(i,j)]=read();
    133             if(!val[p(i,j)]) pl[++tot]=p(i,j);
    134             for(int k=0; k<4; k++)
    135             {
    136                 int mx=i+fang[k][0],my=j+fang[k][1];
    137                 if(mx<1||my<1||mx>n||my>m) continue;
    138                 addedge(p(i,j),p(mx,my));
    139             }
    140         }
    141     for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) mmp[i][j]='_';
    142     spfa();
    143     makeways();
    144     for(int i=1; i<=n; i++)
    145     {
    146         for(int j=1; j<=m; j++)
    147             printf("%c",mmp[i][j]);
    148         printf("
    ");
    149     }
    150     return 0;
    151 }
    View Code
    xjoi ????
      1 #include <bits/stdc++.h>
      2 #define inf 0x3fffffff
      3 using namespace std;
      4 
      5 int n,m,mps[40][40],c1,c2,k,ans;
      6 char s[40][100],tmp1[40],tmp2[40];
      7 int ms[40][8],vis[40][1000],dis[40][1000];
      8 struct node
      9 {
     10     int p,z;
     11 };
     12 queue <node> q;
     13 void topl(node &a,int pl)
     14 {
     15     for(int i=1; i<=ms[pl][0]; i++)
     16         a.z|=(1<<ms[pl][i]);
     17 }
     18 bool getfree(node a)
     19 {
     20     for(int i=0; i<4; i++)
     21     {
     22         int g=(a.z>>i*2)&3;
     23         if(g!=0&&g!=3) return 0;
     24     }
     25     return 1;
     26 }
     27 void spfa()
     28 {
     29     node tmp;
     30     memset(dis,-1,sizeof(dis));
     31     for(int i=1; i<=n; i++)
     32     {
     33         tmp.p=i;
     34         tmp.z=0;
     35         topl(tmp,i);
     36         q.push(tmp);
     37         vis[i][tmp.z]=1;
     38         dis[i][tmp.z]=0;
     39     }
     40     while(!q.empty())
     41     {
     42         node lx=q.front();
     43         q.pop();
     44         if(lx.z==(1<<8)-1)
     45             ans=min(ans,dis[lx.p][lx.z]);
     46         bool ok=getfree(lx);
     47         //stay
     48         for(int i=0; i<(1<<8); i++)
     49         {
     50             if(dis[lx.p][i]==-1) continue;
     51             if(dis[lx.p][i|lx.z]==-1||dis[lx.p][i|lx.z]>dis[lx.p][i]+dis[lx.p][lx.z])
     52             {
     53                 dis[lx.p][i|lx.z]=dis[lx.p][i]+dis[lx.p][lx.z];
     54                 if(!vis[lx.p][i|lx.z])
     55                 {
     56                     tmp.p=lx.p;
     57                     tmp.z=i|lx.z;
     58                     q.push(tmp);
     59                     vis[tmp.p][tmp.z]=1;
     60                 }
     61             }
     62         }
     63         //move
     64         for(int i=1; i<=n; i++)
     65         {
     66             if(mps[lx.p][i]==inf) continue;
     67             int w=ok? 0:mps[lx.p][i];
     68             tmp=lx;
     69             tmp.p=i;
     70             topl(tmp,i);
     71             if(dis[tmp.p][tmp.z]>dis[lx.p][lx.z]+w||dis[tmp.p][tmp.z]==-1)
     72             {
     73                 dis[tmp.p][tmp.z]=dis[lx.p][lx.z]+w;
     74                 if(!vis[tmp.p][tmp.z])
     75                 {
     76                     q.push(tmp);
     77                     vis[tmp.p][tmp.z]=1;
     78                 }
     79             }
     80         }
     81 
     82     }
     83 }
     84 bool check(char a[],char b[])
     85 {
     86     int al=strlen(a),bl=strlen(b);
     87     if(al!=bl) return 0;
     88     for(int i=0; i<al; i++)
     89         if(a[i]!=b[i]) return 0;
     90     return 1;
     91 }
     92 int find(char ch[])
     93 {
     94     for(int i=1; i<=n; i++)
     95         if(check(ch,s[i])) return i;
     96 }
     97 int main()
     98 {
     99     scanf("%d%d",&n,&m);
    100     ans=inf;
    101     for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) mps[i][j]=inf;
    102     for(int i=1; i<=n; i++)
    103         scanf("%s",s[i]);
    104     for(int i=1; i<=m; i++)
    105     {
    106         scanf("%s%s%d",tmp1,tmp2,&k);
    107         c1=find(tmp1);
    108         c2=find(tmp2);
    109         mps[c1][c2]=mps[c2][c1]=min(mps[c1][c2],k);
    110     }
    111     for(int i=1; i<=8; i++)
    112     {
    113         scanf("%s",tmp1);
    114         int c1=find(tmp1);
    115         ms[c1][++ms[c1][0]]=i-1;
    116     }
    117     spfa();
    118     printf("%d
    ",ans);
    119     return 0;
    120 }
    View Code

    格式化插件是个好东西 biiiiiiiiiiiiiiiiiiiiiiiiii

  • 相关阅读:
    github系列:gh-pages
    js 传参乱码问题解决
    nvm安装
    如何创建.babelrc文件?
    Hello World
    python——字符串截取
    python读入写入中文名图片
    VGG16等keras预训练权重文件的下载及本地存放
    在Linux服务器非root权限下搭建TensorFlow框架(Anaconda)
    查看linux服务器上Tensorflow的版本和位置
  • 原文地址:https://www.cnblogs.com/wcz112/p/6255371.html
Copyright © 2011-2022 走看看