zoukankan      html  css  js  c++  java
  • bzoj 4006 [JLOI2015]管道连接(斯坦纳树+状压DP)

    【题目链接】

        http://www.lydsy.com/JudgeOnline/problem.php?id=4006

    【题意】

        给定n点m边的图,连接边(u,v)需要花费w,问满足使k个点中同颜色的点都连通的最小费用。

    【思路】

        题目所求斯坦纳森林。

        如果我们知道满足颜色集合S连通的最小值g[S],则有转移式:

            G[S]=min{ g[s] , G[S’]+G[S-S’] }

        则G[(1<<C)-1]即答案,G[S]定义为使得颜色集合S中所有相同颜色的点都连通的最小值。

        这里的g[S],其实就是一棵包含S中所有颜色的斯坦纳树,即求一棵包含所有颜色在S中的点的斯坦纳树,我们设f[i][st]为在i点且包含点集为st的最小花费则有转移式:

            f[i][st]=min{ f[i][st’]+f[i][st-st’] }

            f[i][st]=min{ f[i’][st]+weight(i,i’) }

        两次状压DP bingo。memset那里可以优化一下,懒得改了 =_=

    【代码】

      1 #include<set>
      2 #include<cmath>
      3 #include<queue>
      4 #include<vector>
      5 #include<cstdio>
      6 #include<cstring>
      7 #include<iostream>
      8 #include<algorithm>
      9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
     10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
     11 using namespace std;
     12 
     13 typedef long long ll;
     14 const int N = 1e3+10;
     15 const int M = 4e3+10;
     16 const int P = 12;  
     17 const int inf = 0xf0f0f0f;
     18 
     19 ll read() {
     20     char c=getchar();
     21     ll f=1,x=0;
     22     while(!isdigit(c)) {
     23         if(c=='-') f=-1; c=getchar();
     24     }
     25     while(isdigit(c))
     26         x=x*10+c-'0',c=getchar();
     27     return x*f;
     28 }
     29 struct Edge { int v,w,nxt;
     30 }e[M<<1];
     31 int en=1,front[N];
     32 void adde(int u,int v,int w) 
     33 {
     34     e[++en]=(Edge){v,w,front[u]}; front[u]=en;
     35 }
     36 struct Node {
     37     int c,w;
     38     bool operator < (const Node& rhs) const {
     39         return c<rhs.c;
     40     }
     41 }ns[P];
     42 
     43 int n,m,K,cnt=0;
     44 int f[N][1<<P],g[1<<P];
     45 
     46 queue<int> q; int inq[N];
     47 
     48 void spfa(int sta)
     49 {
     50     while(!q.empty()) {
     51         int u=q.front(); q.pop(); inq[u]=0;
     52         trav(u,i) {
     53             int v=e[i].v;
     54             if(f[v][sta]>f[u][sta]+e[i].w) {
     55                 f[v][sta]=f[u][sta]+e[i].w;
     56                 if(!inq[v]) 
     57                     inq[v]=1,q.push(v);
     58             }
     59         }
     60     }
     61 }
     62 int solve()
     63 {
     64     int all=1<<cnt;
     65     FOR(sta,1,all-1) {
     66         FOR(i,1,n) {
     67             for(int s=(sta-1)&sta;s;s=(s-1)&sta) 
     68                 f[i][sta]=min(f[i][sta],f[i][s]+f[i][sta-s]);
     69             if(f[i][sta]!=inf) q.push(i),inq[i]=1;
     70         }
     71         spfa(sta);
     72     }
     73     int ans=inf;
     74     FOR(i,1,n) ans=min(ans,f[i][all-1]);
     75     return ans;
     76 }
     77 
     78 int main()
     79 {
     80     freopen("channel.in","r",stdin);
     81     freopen("channel.out","w",stdout);
     82     n=read(),m=read(),K=read();
     83     FOR(i,1,m) {
     84         int u=read(),v=read(),w=read();
     85         adde(u,v,w); adde(v,u,w);
     86     }
     87     FOR(i,1,K) {
     88         ns[i].c=read(),ns[i].w=read();
     89     }
     90     sort(ns+1,ns+K+1);
     91     int C=0;
     92     FOR(i,1,K) {
     93         if(ns[i].c!=ns[i-1].c) C++;
     94         ns[i].c=C;
     95     }
     96     memset(g,0xf,sizeof(g));
     97     int all=1<<C;
     98     FOR(sta,1,all-1) {
     99         memset(f,0xf,sizeof(f));
    100         cnt=0; FOR(i,1,K) if((1<<ns[i].c-1)&sta) f[ns[i].w][1<<cnt++]=0;
    101         g[sta]=solve();
    102     }
    103     FOR(sta,1,all-1) {
    104         for(int s=(sta-1)&sta;s;s=(s-1)&sta)
    105             g[sta]=min(g[sta],g[s]+g[sta-s]);
    106     }
    107     printf("%d
    ",g[all-1]);
    108     return 0;
    109 }
  • 相关阅读:
    低情商大神的思维,高情商的你会懂么?为什么非常多计算机老师都是坏脾气?为什么提问没人回答?为什么要通过网络自主学习?
    Add Binary
    Codeforces Round #252 (Div. 2) B. Valera and Fruits(模拟)
    cocos2d-x项目101次相遇: Scenes , Director, Layers, Sprites
    Android应用性能优化系列视图篇——隐藏在资源图片中的内存杀手
    Android屏幕信息获取
    android 比较靠谱的图片压缩
    Android 图片压缩,基于比例和质量压缩
    android Bitmap类方法属性 详细说明
    Android入门——Bitmap和BitmapFactory
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5301180.html
Copyright © 2011-2022 走看看