zoukankan      html  css  js  c++  java
  • HDU 4085 Peach Blossom Spring

    斯坦纳树。

    最后可以是森林,在计算出每个联通状态的最小费用后,还需要进行一次$dp$。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int INF=0x7FFFFFFF;
    int T,n,m,k;
    vector<int>g[60];
    int val[60][60],id[60],d[60][1200],dp[1200];
    int f[60*10000];
    queue<int>Q;
    
    void spfa()
    {
        while(!Q.empty())
        {
            int h = Q.front(); Q.pop(); f[h]=0;
            int x=h/10000,y=h%10000;
            for(int i=0;i<g[x].size();i++)
            {
                int to = g[x][i];
    
                if(to<2*k)
                {
                    if(((1<<to)&y)==0)
                    {
                        if(d[x][y]+val[x][to]<d[to][y|(1<<to)])
                            d[to][y|(1<<to)]=d[x][y]+val[x][to];
                    }
                }
    
                else
                {
                    if(d[x][y]+val[x][to]<d[to][y])
                    {
                        d[to][y] = d[x][y]+val[x][to];
                        if(f[to*10000+y]==0)
                        {
                            f[to*10000+y]=1;
                            Q.push(to*10000+y);
                        }
                    }
                }
            }
        }
    }
    
    bool check(int x)
    {
        int sum1=0,sum2=0;
        for(int i=0;i<=k-1;i++) if(x&(1<<i)) sum1++;
        for(int i=k;i<=2*k-1;i++) if(x&(1<<i)) sum2++;
        if(sum1==sum2) return 1;
        return 0;
    }
    
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d",&n,&m,&k);
    
            for(int i=0;i<n;i++)
            {
                id[i]=i;
                g[i].clear();
            }
    
            id[k]=n-k; for(int i=k+1;i<=2*k-1;i++) id[i]=id[i-1]+1;
            id[n-k]=k; for(int i=n-k+1;i<=n-1;i++) id[i]=id[i-1]+1;
    
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++) val[i][j]=INF;
            memset(f,0,sizeof f);
    
            for(int i=1;i<=m;i++)
            {
                int a,b,c; scanf("%d%d%d",&a,&b,&c);
                a--; b--; a=id[a]; b=id[b];
                val[a][b]=min(val[a][b],c);
                val[b][a]=val[a][b];
                g[a].push_back(b);
                g[b].push_back(a);
            }
    
            int st = 1<<(2*k);
    
            for(int j=0;j<st;j++)
                for(int i=0;i<n;i++) d[i][j]=INF;
    
            for(int i=0;i<n;i++)
            {
                if(i<2*k) d[i][1<<i]=0;
                else d[i][0]=0;
            }
    
            for(int j=0;j<st;j++)
            {
                for(int i=0;i<n;i++)
                {
                    if(i<2*k)
                    {
                        if(((1<<i)&j)==0) continue;
                        for (int x = j; x; x = (x-1)&j)
                        {
                            int A=x ,B=j-A;
                            if(d[i][A|(1<<i)]!=INF&&d[i][B|(1<<i)]!=INF)
                                d[i][j] = min(d[i][j], d[i][A|(1<<i)]+d[i][B|(1<<i)]);
                        }
                    }
                    else
                    {
                        for (int x = j; x; x = (x-1)&j)
                        {
                            int A=x ,B=j-A;
                            if(d[i][A]!=INF&&d[i][B]!=INF)
                                d[i][j] = min(d[i][j], d[i][A]+d[i][B]);
                        }
                    }
    
                    if(d[i][j]!=INF) Q.push(i*10000+j);
                }
                spfa();
            }
    
            for(int j=0;j<st;j++)
            {
                dp[j]=INF;
                for(int i=0;i<n;i++) dp[j]=min(dp[j],d[i][j]);
            }
    
            for(int j=0;j<st;j++)
            {
                for (int x = j; x; x = (x-1)&j)
                {
                    int A=x ,B=j-A;
                    if(check(A)&&check(B)&&dp[A]!=INF&&dp[B]!=INF)
                        dp[j]=min(dp[j],dp[A]+dp[B]);
                }
            }
    
            if(dp[st-1]!=INF) printf("%d
    ",dp[st-1]);
            else printf("No solution
    ");
        }
        return 0;
    }
  • 相关阅读:
    SpringBoot及Vue3.0 登录验证码实现
    SpringBoot 文件上传、下载、显示
    Redis持久化
    Redis持久化之RDB、AOF详解
    SpringBoot AOP 记录操作日志、异常日志
    JAVA后端《持续集成 持续交付 持续部署》
    MySQL Binlog 介绍
    谷歌浏览器chrome即将在2020年底停止支持flash,我们程序员该怎么办
    年薪170万的阿里P8级员工征婚有感--话说阿里真有钱,这员工要求的条件真多
    为什么百度只抓取了首页而不抓取我的网站的内页的原因分析
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6638320.html
Copyright © 2011-2022 走看看