Live2d Test Env

HDU - 3311: Dig The Wells (斯坦纳树)

题意:给你n个寺庙,m个村庄,p条路,现在你要在这n+m个位置中选出若干个位置打井,每个位置打井的费用会告诉你,同时p条路也有修建费用,现在每个寺庙都住着一个和尚,问你最小的费用让这n个和尚都能喝上水。

思路:可以对照之前做的MST题目(https://www.cnblogs.com/hua-dong/p/11164702.html)。 之前那个题是让所有点都喝上水,让后新建一个0号节点,向所有点连边,边权是打井的费用,然后跑最小生成树。   而本题是让所有寺庙有水,不关心村庄,所以应该是斯坦纳树模型。

斯坦纳树:使得关键点连通的最小代价。  dp[i][j]代表以i为根,连通状态为j的最小代价。 不停地子集DP+dijkstra....

 

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=2010;
const int inf=1e9;
int Laxt[maxn*7],Next[maxn*7],To[maxn*7],Len[maxn*7],cnt;
int N,M,dis[maxn][maxn],dp[maxn][maxn],vis[maxn],V;
void add(int u,int v,int len)
{
    Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v;
    Len[cnt]=len;
}
void SPFA()
{
    rep(i,0,V) rep(j,0,V) dis[i][j]=inf;
    rep(i,0,V) {
        queue<int>q;
        dis[i][i]=0;
        q.push(i);
        while(!q.empty()){
            int u=q.front(); q.pop(); vis[u]=0;
            for(int j=Laxt[u];j;j=Next[j]){
                int v=To[j];
                if(dis[i][v]>dis[i][u]+Len[j]){
                    dis[i][v]=dis[i][u]+Len[j];
                    if(!vis[v]){vis[v]=1; q.push(v);}
                }
            }
        }
    }

}
void solve()
{
    rep(i,0,N)
     rep(j,0,V) dp[j][1<<i]=dis[i][j];
    rep(i,1,(1<<(N+1))-1){
        if(!((i-1)&i)) continue; //只有一位,不管,上面已经给出。
        rep(j,0,V){
            dp[j][i]=inf;
            for(int k=i;k;k=(k-1)&i)
            dp[j][i]=min(dp[j][i],dp[j][k]+dp[j][i^k]);
        }
        rep(k,0,V){
           if(dp[k][i]==inf) continue;
           rep(j,0,V)
             dp[j][i]=min(dp[j][i],dp[k][i]+dis[k][j]);
        }
    }
}
int main()
{
    int P,u,v,x;
    while(~scanf("%d%d%d",&N,&M,&P)){
        V=N+M;
        rep(i,0,V) Laxt[i]=0; cnt=0;
        rep(i,1,V){
            scanf("%d",&x);
            add(0,i,x); add(i,0,x);
        }
        rep(i,1,P){
            scanf("%d%d%d",&u,&v,&x);
            add(u,v,x); add(v,u,x);
        }
        SPFA();
        solve();
        printf("%d\n",dp[0][(1<<(N+1))-1]);
    }
    return 0;
}

 

posted @ 2019-07-17 10:35  nimphy  阅读(355)  评论(0编辑  收藏  举报