posts - 43,  comments - 9,  trackbacks - 0
http://acm.hdu.edu.cn/showproblem.php?pid=3311

给定6个基础点,和1000个辅助点,以及无向边若干。
求一棵代价最小的生成子树,使得6个基础点连通。
http://en.wikipedia.org/wiki/Steiner_tree_problem

方法一:
状态DP。
一棵树,实际上可以看成是由两棵子树拼接而成,或者一棵树扩展一条边筛选。而要完整地表示一棵子树,需要记录它的根,和对6个基础点的覆盖状态。
这样求一棵大树,可以枚举接合点,以及两个子树的覆盖状态。
若dp[i][j],i表示接合点,j表示覆盖状态,那么dp[i][j]=min{dp[i][k]+dp[i][j^k]}。
直接扩展一条边, 可以在保持j不变的情况下, 优先队列广搜, 大大降低复杂度.

方法二:
spfa。
dp[i][j]意义同上。一个点(i,j),对每个邻接点i',枚举那一头的状态j',然后用dp[i][j]+dp[i'][j']+way[i][i']去更新dp[i][j|j']和dp[i'][j|j']。

ps. topcoder srm 470 div1 level3是此题升级版.

  1 #include <string>
  2 #include <vector>
  3 #include <list>
  4 #include <map>
  5 #include <queue>
  6 #include <stack>
  7 #include <set>
  8 #include <iostream>
  9 #include <sstream>
 10 #include <numeric>
 11 #include <algorithm>
 12 #include <cmath>
 13 #include <cctype>
 14 #include <cstdlib>
 15 #include <cstdio>
 16 #include <cstring>
 17 using namespace std;
 18 
 19 #define CLR(x) memset((x),0,sizeof(x))
 20 #define SET(x,y) memset((x),(y),sizeof(x))
 21 #define REP(i,x) for(int i=0;i<(x);i++)
 22 #define FOR(i,x,y) for(int i=(x);i<(y);i++)
 23 #define VI vector<int> 
 24 #define PB(i,x) (i).push_back(x)
 25 #define MP(x,y) make_pair((x),(y))
 26 
 27 struct EDGE{
 28     int v,e,d;
 29 }edg[20000];
 30 int ecnt, gg[1006];
 31 
 32 struct HEAP{
 33     int v,d;
 34     void set(int nv, int nd){v=nv;d=nd;}
 35 }hp[1006*(1<<6)*10];
 36 int sz;
 37 bool vis[1006];
 38 
 39 int dp[1006][1<<6];
 40 int N, M, P;
 41 
 42 bool cmp(const HEAP &a, const HEAP &b)
 43 return a.d>b.d; }
 44 
 45 void addedge(int u, int v, int d)
 46 {
 47     edg[ecnt].v=v; edg[ecnt].d=d; edg[ecnt].e=gg[u]; gg[u]=ecnt++;
 48     edg[ecnt].v=u; edg[ecnt].d=d; edg[ecnt].e=gg[v]; gg[v]=ecnt++;
 49 }
 50 
 51 int steiner()
 52 {
 53     int up = 1<<(N+1);
 54     SET(dp,-1);
 55     REP(i,N+1) dp[i][1<<i]=0;
 56     FOR(i,N+1,N+M+1) dp[i][0]=0;
 57     REP(i,up){
 58         REP(j,N+M+1){
 59             for(int k=i; k>0; k=(k-1)&i){
 60                 if(dp[j][k]!=-1 && dp[j][i^k]!=-1)
 61                     if(dp[j][i]==-1 || dp[j][i]>dp[j][k]+dp[j][i^k])
 62                         dp[j][i]=dp[j][k]+dp[j][i^k];
 63             }
 64         }
 65         sz=0;
 66         CLR(vis);
 67         REP(j,N+M+1if(dp[j][i]!=-1){
 68             hp[sz++].set(j,dp[j][i]);
 69             push_heap(hp, hp+sz, cmp);
 70         }
 71         while(sz){
 72             int now=hp[0].v;
 73             pop_heap(hp, hp+sz--,cmp);
 74             if(vis[now])continue;
 75             vis[now]=true;
 76             for(int e=gg[now]; ~e; e=edg[e].e){
 77                 int to=edg[e].v, td=dp[now][i]+edg[e].d;
 78                 if(dp[to][i]==-1 || dp[to][i]>td){
 79                     dp[to][i]=td;
 80                     hp[sz++].set(to,td);
 81                     push_heap(hp, hp+sz, cmp);
 82                 }
 83             }
 84         }
 85     }
 86     return dp[0][up-1];
 87 }
 88 
 89 int main()
 90 {
 91     while(~scanf("%d %d %d"&N, &M, &P)){
 92         int u, v, d;
 93         SET(gg,-1); ecnt=0;
 94         REP(i,N+M){
 95             scanf("%d"&d);
 96             addedge(0,i+1, d);
 97         }
 98         REP(i,P){
 99             scanf("%d %d %d"&u, &v, &d);
100             addedge(u,v,d);
101         }
102         int ret=steiner();
103         printf("%d\n", ret);
104     }
105     return 0;
106 }

posted on 2010-05-27 16:21 wolf5x 阅读(568) 评论(0)  编辑 收藏 引用 所属分类: acm_icpc

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2010年5月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

"Do not spend all your time on training or studying - this way you will probably become very exhausted and unwilling to compete more. Whatever you do - have fun. Once you find programming is no fun anymore – drop it. Play soccer, find a girlfriend, study something not related to programming, just live a life - programming contests are only programming contests, and nothing more. Don't let them become your life - for your life is much more interesting and colorful." -- Petr

留言簿(3)

随笔分类(59)

随笔档案(43)

cows

搜索

  •  

最新评论

评论排行榜