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
  • 相关阅读:
    SQL Server Audit监控触发器状态
    SQL Server 数据变更时间戳(timestamp)在复制中的运用
    SQL Server 更改跟踪(Chang Tracking)监控表数据
    SQL Server 变更数据捕获(CDC)监控表数据
    SQL Server 事件通知(Event notifications)
    SQL Server 堆表行存储大小(Record Size)
    SQL Server DDL触发器运用
    SQL Server 默认跟踪(Default Trace)
    SQL Server 创建数据库邮件
    SQL Server 跨网段(跨机房)FTP复制
  • 原文地址:https://www.cnblogs.com/starve/p/13793569.html
Copyright © 2011-2022 走看看