zoukankan      html  css  js  c++  java
  • 「JLOI2015」管道连接(求相同颜色的点联通即可,合并斯坦纳树)

    题:https://loj.ac/problem/2110

    题意:给定无向图,要求选一些边,让指定的相同颜色的点联通。

    分析:

       在求解单一的斯坦纳树,我们可以得到连接起点的子集的最小值g[];

       然后就针对颜色集f[];

       若某个状态set要组成x颜色和y颜色,那么f[]初始为在g中x颜色对应的点集和y颜色对应的点集;

       最后对f[]进行枚举子集更新最小值;

    #include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    #define MP make_pair
    #define lson root<<1,l,midd
    #define rson root<<1|1,midd+1,r
    typedef long long ll;
    const int mod=1e9+7;
    const int M=1e3+100;
    const int inf=0x3f3f3f3f;
    const ll INF=1e18;
    int dp[M][M];
    struct qnode{
        int v;
        ll c;
        qnode(int _v=0,ll _c=0):v(_v),c(_c){}
        bool operator <(const qnode &r)const{
         return c>r.c;
        }
    };
    struct Edge{
        int v;
        ll cost;
        Edge(int _v=0,ll _cost=0):v(_v),cost(_cost){}
    };
    vector<Edge>E[M];
    bool vis[M];
    priority_queue<qnode>que;
    void Dij(int cursta){
        memset(vis,false,sizeof(vis));
        qnode tmp;
        while(!que.empty()){
            tmp=que.top();
            que.pop();
            int u=tmp.v;
            if(vis[u])continue;
                vis[u]=true;
            for(int i=0;i<E[u].size();i++){
                int v=E[tmp.v][i].v;
                int cost=E[u][i].cost;
                if(!vis[v]&&dp[v][cursta]>dp[u][cursta]+cost){
                    dp[v][cursta]=dp[u][cursta]+cost;
                    que.push(qnode(v,dp[v][cursta]));
                }
            }
        }
    }
    void addedge(int u,int v,ll w){
        E[u].push_back(Edge(v,w));
    }
    int C[20],all,f[M],g[M];
    int main(){
        int n,m,p;
        scanf("%d%d%d",&n,&m,&p);
        for(int u,v,w,i=1;i<=m;i++){
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w);
            addedge(v,u,w);
        }
        memset(dp,0x3f,sizeof(dp));
        memset(f,0x3f,sizeof(f));
        int limit=dp[0][0];
        for(int c,d,i=1;i<=p;i++){
            scanf("%d%d",&c,&d);
            C[c]|=(1<<(i-1));
            all|=(1<<(c-1));
            dp[d][0]=dp[d][1<<(i-1)]=0;
        }
        for(int s=1;s<(1<<p);s++){
            for(int i=1;i<=n;i++){
                for(int subset=s&(s-1);subset;subset=s&(subset-1)){
                    dp[i][s]=min(dp[i][s],dp[i][subset]+dp[i][s^subset]);
                }
                if(dp[i][s]<limit) que.push(qnode(i,dp[i][s]));
            }
            Dij(s);
            g[s]=inf;
            for(int i=1;i<=n;i++)
                g[s]=min(g[s],dp[i][s]);
        }
        for(int s=all;s;s=all&(s-1)){
            int sum=0;
            for(int i=1;i<=p;i++)
                if((s>>(i-1)) & 1) sum|=C[i];
            f[s]=g[sum];
        }
        for(int s=1;s<=all;s++)
            for(int subset=s&(s-1);subset;subset=s&(subset-1))
                f[s]=min(f[s],f[s^subset]+f[subset]);
        printf("%d
    ",f[all]);
        return 0;
    }
    View Code
  • 相关阅读:
    Python几种主流框架
    Python测试框架
    Python测试工具开发
    robotFramework——通用的自动化测试框架
    依赖数据库的单元测试——DBUnit
    SpringTest——Spring在Junit上进一步封装,集成的测试模块
    linux---网络配置
    linux-----初学命令和理解
    Liunx----vi编辑器
    虚拟机---网络设置
  • 原文地址:https://www.cnblogs.com/starve/p/13793569.html
Copyright © 2011-2022 走看看