BZOJ4006: [JLOI2015]管道连接(斯坦纳树,状压DP)

Time Limit: 30 Sec  Memory Limit: 128 MB
Submit: 1171  Solved: 639
[Submit][Status][Discuss]

Description

小铭铭最近进入了某情报部门,该部门正在被如何建立安全的通道连接困扰。

该部门有 n 个情报站,用 1 到 n 的整数编号。给出 m 对情报站 ui;vi 和费用 wi,表示情

报站 ui 和 vi 之间可以花费 wi 单位资源建立通道。

如果一个情报站经过若干个建立好的通道可以到达另外一个情报站,那么这两个情报站就

建立了通道连接。形式化地,若 ui 和 vi 建立了通道,那么它们建立了通道连接;若 ui 和 vi 均

与 ti 建立了通道连接,那么 ui 和 vi 也建立了通道连接。

现在在所有的情报站中,有 p 个重要情报站,其中每个情报站有一个特定的频道。小铭铭

面临的问题是,需要花费最少的资源,使得任意相同频道的情报站之间都建立通道连接。

Input

第一行包含三个整数 n;m;p,表示情报站的数量,可以建立的通道数量和重要情报站的数

量。接下来 m 行,每行包含三个整数 ui;vi;wi,表示可以建立的通道。最后有 p 行,每行包含

两个整数 ci;di,表示重要情报站的频道和情报站的编号。

Output

输出一行一个整数,表示任意相同频道的情报站之间都建立通道连接所花费的最少资源总量。

Sample Input

5 8 4
1 2 3
1 3 2
1 5 1
2 4 2
2 5 1
3 4 3
3 5 1
4 5 1
1 1
1 2
2 3
2 4

Sample Output

4

HINT

选择 (1; 5); (3; 5); (2; 5); (4; 5) 这 4 对情报站连接。

对于 100% 的数据,0 <ci <= p <= 10; 0 <ui;vi;di <= n <= 1000; 0 <= m <= 3000; 0 <= wi <=

20000。

Source

斯坦纳森林

设$f[i][sta]$表示$i$号节点,与关键节点的联通性为$sta$时的最小值

假设我们已经求出了$f$

那么我们令$g[sta]$表示,颜色联通性为$sta$时的最小值

$g$比较好求,枚举子集转移就可以

$f$的话,如果学过斯坦纳树也比较好求

按照套路,两种转移方法,一种是枚举子集,一种是SPFA

#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int MAXN = 1e6 + 10;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < ‘0‘ || c > ‘9‘) {if(c == ‘-‘) f = -1; c = getchar();}
    while(c >= ‘0‘ && c <= ‘9‘) {x = x * 10 + c - ‘0‘; c = getchar();}
    return x * f;
}
int N, M, P;
struct node {
    int u, v, w, nxt;
}E[MAXN];
int head[MAXN], num = 1;
inline void AddEdge(int x, int y,int z) {
    E[num].u = x; E[num].v = y; E[num].w = z;
    E[num].nxt = head[x]; head[x] = num++;
}
struct Point {
    int color, ID;
}a[MAXN];
int f[1051][1051], g[1051];
int vis[MAXN], sum[MAXN];
queue<int>q;
void SPFA(int now) {
    while(q.size() != 0) {
        int p = q.front(); q.pop(); vis[p] = 0;
        for(int i = head[p]; i != -1; i = E[i].nxt) {
            int v = E[i].v;
            if(f[v][now] > f[p][now] + E[i].w) {
                f[v][now] = f[p][now] + E[i].w;
                if(!vis[v]) vis[v] = 1, q.push(v);
            }
        }
    }
}
int tmp[11];
bool check(int sta) {
    memset(tmp, 0, sizeof(tmp));
    for(int i = 1; i <= 10; i++)
        if(sta & (1 << i - 1)) tmp[a[i].color]++;
    for(int i = 1; i <= 10; i++)
        if(tmp[i] && tmp[i] != sum[i]) return 0;
    return 1;
}
int main() {
    #ifdef WIN32
    freopen("a.in", "r", stdin);
    #endif
    memset(head, -1, sizeof(head));
    N = read(), M = read(), P = read();
    for(int i = 1; i <= M; i++) {
        int x = read(), y = read(), z = read();
        AddEdge(x, y, z);AddEdge(y, x, z);
    }
    memset(f, 0x3f, sizeof(f));
    memset(g, 0x3f, sizeof(g));
    for(int i = 1; i <= P; i++)
        a[i].color = read(), a[i].ID = read(), sum[a[i].color]++,f[a[i].ID][1 << (i - 1)] = 0;
    int limit = (1 << P) - 1;
    for(int sta = 0; sta <= limit; sta++) {
        for(int i = 1; i <= N; i++) {
            for(int S = sta; S; S = (S - 1) & sta)
                f[i][sta] = min(f[i][sta], f[i][S] + f[i][sta - S]);
            q.push(i),vis[i] = 1;
        }
        SPFA(sta);
    }
    for(int sta = 0; sta <= limit; sta++)
        for(int i = 1; i <= N; i++)
            g[sta] = min(g[sta], f[i][sta]);
    for(int sta = 0; sta <= limit; sta++)
        if(check(sta))
            for(int S = sta; S; S = (S - 1) & sta)
                if(check(S))
                    g[sta] = min(g[sta], g[S] + g[sta - S]);
    printf("%d", g[(1 << P) - 1]);
    return 0;
}

原文地址:https://www.cnblogs.com/zwfymqz/p/8977219.html

时间: 2024-10-01 02:46:56

BZOJ4006: [JLOI2015]管道连接(斯坦纳树,状压DP)的相关文章

【BZOJ4774/4006】修路/[JLOI2015]管道连接 斯坦纳树

[BZOJ4774]修路 Description 村子间的小路年久失修,为了保障村子之间的往来,法珞决定带领大家修路.对于边带权的无向图 G = (V, E),请选择一些边,使得1 <= i <= d, i号节点和 n - i + 1 号节点可以通过选中的边连通,最小化选中的所有边的权值和. Input 第一行两个整数 n, m,表示图的点数和边数.接下来的 m行,每行三个整数 ui, vi, wi,表示有一条 ui 与 vi 之间,权值为 wi 的无向边. 1 <= d <= 4

BZOJ2595: [Wc2008]游览计划(斯坦纳树,状压DP)

Time Limit: 10 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 2030  Solved: 986[Submit][Status][Discuss] Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个景点:否则表示控制该方块至少需要的志愿者数目. 相邻的整数用 (若干个) 空格隔开,行首行末也可能有多余的空格. Outpu

bzoj4006 [JLOI2015]管道连接

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4006 [题解] 即求斯坦纳森林-- 然后我们发现可以先把所有点全当做重要点做一遍steiner tree. 然后我们可以求出联通状态为S的时候的最小花费 然后子集更新即可.(再一遍dp) 注意只需要做一遍就够了!!! 而且斯坦纳树板子要用对(大概快4倍左右) # include <queue> # include <stdio.h> # include <string.

HDU 4085 Peach Blossom Spring 斯坦纳树 状态压缩DP+SPFA

状态压缩dp+spfa解斯坦纳树 枚举子树的形态 dp[i][j] = min(dp[i][j], dp[i][k]+dp[i][l]) 其中k和l是对j的一个划分 按照边进行松弛 dp[i][j] = min(dp[i][j], dp[i'][j]+w[i][j])其中i和i'之间有边相连 #include <cstdio> #include <cstring> #include <queue> using namespace std; const int maxn

BZOJ_4006_[JLOI2015]管道连接_斯坦纳树

题意: 小铭铭最近进入了某情报部门,该部门正在被如何建立安全的通道连接困扰. 该部门有 n 个情报站,用 1 到 n 的整数编号.给出 m 对情报站 ui;vi 和费用 wi,表示情 报站 ui 和 vi 之间可以花费 wi 单位资源建立通道. 如果一个情报站经过若干个建立好的通道可以到达另外一个情报站,那么这两个情报站就 建立了通道连接.形式化地,若 ui 和 vi 建立了通道,那么它们建立了通道连接:若 ui 和 vi 均 与 ti 建立了通道连接,那么 ui 和 vi 也建立了通道连接.

【BZOJ 2595】2595: [Wc2008]游览计划 (状压DP+spfa,斯坦纳树?)

2595: [Wc2008]游览计划 Time Limit: 10 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 1572  Solved: 739 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个景点:否则表示控制该方块至少需要的志愿者数目. 相邻的整数用 (若干个) 空格隔开,行首行末也可能有多余的空格. Output 由 N

BZOJ 2595: [Wc2008]游览计划 [DP 状压 斯坦纳树 spfa]【学习笔记】

传送门 题意:略 论文 <SPFA算法的优化及应用> http://www.cnblogs.com/lazycal/p/bzoj-2595.html 本题的核心就是求斯坦纳树: Steiner Tree: Given an undirected graph with non-negative edge weights and a subset of vertices, usually referred to as terminals, the Steiner tree problem in g

【ZJOI2017练习】D3T2 road(斯坦纳树,状压DP)

题意: 对于边带权的无向图 G = (V, E),请选择一些边, 使得1<=i<=d,i号节点和 n ? i + 1 号节点可以通过选中的边连通, 最小化选中的所有边的权值和. d<=4 n<=10000 m<=10000 w[i]<=1000 思路: 求一个最小生成树(或森林),使得若干组点对各自联通由于d很小(<=4),考虑采用状压DP的做法.令1,2,..d和n,n-1...n-d+1为2d个特殊点先考虑生成树的情况:设F[i][j](i=1,2...n j

[JLOI2015]管道连接

题目描述 小铭铭最近进入了某情报部门,该部门正在被如何建立安全的通道连接困扰.该部门有 n 个情报站,用 1 到 n 的整数编号.给出 m 对情报站 ui;vi 和费用 wi,表示情报站 ui 和 vi 之间可以花费 wi 单位资源建立通道. 如果一个情报站经过若干个建立好的通道可以到达另外一个情报站,那么这两个情报站就建立了通道连接.形式化地,若 ui 和 vi 建立了通道,那么它们建立了通道连接:若 ui 和 vi 均与 ti 建立了通道连接,那么 ui 和 vi 也建立了通道连接. 现在在