zoukankan      html  css  js  c++  java
  • bzoj4774: 修路

    Description

    村子间的小路年久失修,为了保障村子之间的往来,法珞决定带领大家修路。对于边带权的无向图 G = (V, E),
    请选择一些边,使得1 <= i <= d, i号节点和 n - i + 1 号节点可以通过选中的边连通,最小化选中的所有边
    的权值和。

    Input

    第一行两个整数 n, m,表示图的点数和边数。接下来的 m行,每行三个整数 ui, vi, wi,表示有一条 ui 与 vi 
    之间,权值为 wi 的无向边。
    1 <= d <= 4
    2d <= n <= 10^4
    0 <= m <= 10^4
    1 <= ui, vi <= n
    1 <= wi <= 1000

    Output

    一行一个整数,表示答案,如果无解输出-1
    将要求联通的2d个点及其子集求一次斯坦纳树,最后再用状压dp得出最小权值和
    #include<cstdio>
    #include<cstring>
    #include<queue>
    const int N=10007,inf=0x3f3f3f3f;
    int n,m,d,mx;
    int es[N*2],enx[N*2],ev[N*2],e0[N],ep=2;
    int f[256][N],g[16];
    struct node{
        int w,l;
        bool operator<(const node&x)const{return l>x.l;}
    };
    std::priority_queue<node>q;
    void mins(int&a,int b){if(a>b)a=b;}
    int main(){
        scanf("%d%d%d",&n,&m,&d);
        for(int i=0,a,b,c;i<m;++i){
            scanf("%d%d%d",&a,&b,&c);
            es[ep]=b;enx[ep]=e0[a];ev[ep]=c;e0[a]=ep++;
            es[ep]=a;enx[ep]=e0[b];ev[ep]=c;e0[b]=ep++;
        }
        mx=1<<d;
        memset(f,0x3f,sizeof(f[0])*mx*mx);
        memset(g,0x3f,sizeof g);
        for(int i=1;i<=d;++i)f[1<<i-1][i]=f[1<<i+d-1][n+1-i]=0;
        for(int i=1;i<mx*mx;++i){
            int*l=f[i];
            for(int j=i-1&i;j>(i^j);j=j-1&i){
                for(int w=1,*l1=f[j],*l2=f[i^j];w<=n;++w)mins(l[w],l1[w]+l2[w]);
            }
            for(int w=1;w<=n;++w)if(l[w]<inf)q.push((node){w,l[w]});
            while(!q.empty()){
                node w=q.top();q.pop();
                if(w.l!=l[w.w])continue;
                for(int e=e0[w.w];e;e=enx[e]){
                    int u=es[e],d=w.l+ev[e];
                    if(l[u]>d)q.push((node){u,l[u]=d});
                }
            }
            if((i&mx-1)==(i>>d)){
                int ml=inf;
                for(int j=1;j<=n;++j)mins(ml,l[j]);
                mins(g[i>>d],ml);
            }
        }
        for(int i=1;i<mx;++i){
            for(int j=i-1&i;j;j=j-1&i)mins(g[i],g[j]+g[i^j]);
        }
        printf("%d",g[mx-1]!=inf?g[mx-1]:-1);
        return 0;
    }
  • 相关阅读:
    translations.dart阅读
    # objc-weak 阅读
    Objective-C Runtime2.0(-)
    iOS图文混排
    BestCoder Round #85 抽屉原理/贪心/质因数
    hdu 5763 Another Meaning KMP+DP(多校)
    hdu 5775 Bubble Sort 树状数组(多校)
    BestCoder Round #84
    hdu 5724 SG函数+状压(多校)
    hdu 5723 最小生成树+dfs (多校)
  • 原文地址:https://www.cnblogs.com/ccz181078/p/6574471.html
Copyright © 2011-2022 走看看