zoukankan      html  css  js  c++  java
  • 【bzoj5180】[Baltic2016]Cities 斯坦纳树

    这题一看显然是一个裸的斯坦纳树

    我们用$f[i][j]$表示经过的路径中包含了状态$i$所表示的点,且连接了$j$号点的最短路径。

    显然,$f[i][j]=min{f[i$^$k][j]+f[k][j]}$, 其中$i $&$ k = k$。

    转移完毕后,跑一个最短路去更新一遍。

    那么显然这题的时间复杂度是$O(2^k imes 最短路时间复杂度)$。

    但是这题神TM卡SPFA。。。。

    我后来改写了$dij$,再加了个避免重复更新的判断,才过了...

     1 #include<bits/stdc++.h>
     2 #define M 100005
     3 #define L long long
     4 #define INF 1926081719260817LL
     5 using namespace std;
     6 struct edge{int u,v,next;}e[M<<2]={0}; int head[M]={0},use=0; 
     7 void add(int x,int y,int z){use++;e[use].u=y;e[use].v=z;e[use].next=head[x];head[x]=use;}
     8 L f[1<<5][M]={0}; 
     9 struct node{
    10     int u; L dis; node(){u=dis=0;}
    11     node(int uu,L diss){u=uu; dis=diss;}
    12     friend bool operator <(node a,node b){return a.dis>b.dis;}
    13 }; priority_queue<node> q; 
    14 bool vis[M]={0};
    15 void spfa(L dfn[]){
    16     memset(vis,0,sizeof(vis));
    17     while(!q.empty()){
    18         node uu=q.top(); q.pop(); 
    19         int u=uu.u;
    20         if(vis[u]) continue; vis[u]=1;
    21         for(int i=head[u];i;i=e[i].next)
    22         if(dfn[e[i].u]>dfn[u]+e[i].v){
    23             dfn[e[i].u]=dfn[u]+e[i].v;
    24             q.push(node(e[i].u,dfn[e[i].u]));
    25         }
    26     }
    27 }
    28 int n,m,k,p[10]={0};
    29 
    30 int main(){
    31     scanf("%d%d%d",&n,&k,&m);
    32     for(int i=0;i<(1<<k);i++)
    33     for(int j=1;j<=n;j++) f[i][j]=INF;
    34     for(int i=0;i<k;i++){
    35         scanf("%d",p+i);
    36         f[1<<i][p[i]]=0; 
    37     }
    38     for(int i=1;i<=m;i++){
    39         int x,y,z; scanf("%d%d%d",&x,&y,&z);
    40         add(x,y,z); add(y,x,z);
    41     }
    42     for(int i=1;i<(1<<k);i++){
    43         for(int j=i;j;j=i&(j-1)){
    44             for(int k=1;k<=n;k++)
    45             f[i][k]=min(f[i][k],f[j][k]+f[i^j][k]);
    46         }
    47         for(int k=1;k<=n;k++)
    48         if(f[i][k]!=INF) q.push(node(k,f[i][k]));
    49         spfa(f[i]);
    50     }
    51     L minn=INF;
    52     for(int i=1;i<=n;i++) 
    53     minn=min(minn,f[(1<<k)-1][i]);
    54     cout<<minn<<endl;
    55 }

     

  • 相关阅读:
    GCD 使用说明
    iOS操作系统的层次结构
    Objective-C 类型转换
    UIView和Masonry实现动画效果
    iOS 常用手势
    SDUT 2610 Boring Counting(离散化+主席树区间内的区间求和)
    HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)
    NBUT 1525 Cow Xor(01字典树+前缀思想)
    HDU 4825 Xor Sum(经典01字典树+贪心)
    HDU 1069 Monkey and Banana(二维偏序LIS的应用)
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/9249429.html
Copyright © 2011-2022 走看看