zoukankan      html  css  js  c++  java
  • [BZOJ4006][JLOI2015]管道连接

    [BZOJ4006][JLOI2015]管道连接

    试题描述

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

    该部门有 (n) 个情报站,用 (1)(n) 的整数编号。给出 (m) 对情报站 (u_i,v_i) 和费用 (w_i),表示情报站 (u_i)(v_i) 之间可以花费 (w_i) 单位资源建立通道。

    如果一个情报站经过若干个建立好的通道可以到达另外一个情报站,那么这两个情报站就建立了通道连接。形式化地,若 (u_i)(v_i) 建立了通道,那么它们建立了通道连接;若 (u_i)(v_i) 均与 (t_i) 建立了通道连接,那么 (u_i)(v_i) 也建立了通道连接。

    现在在所有的情报站中,有 (p) 个重要情报站,其中每个情报站有一个特定的频道。小铭铭面临的问题是,需要花费最少的资源,使得任意相同频道的情报站之间都建立通道连接。

    输入

    第一行包含三个整数 (n,m,p),表示情报站的数量,可以建立的通道数量和重要情报站的数量。接下来 (m) 行,每行包含三个整数 (u_i,v_i,w_i),表示可以建立的通道。最后有 (p) 行,每行包含两个整数 (c_i,d_i),表示重要情报站的频道和情报站的编号。

    输出

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

    输入示例

    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
    

    输出示例

    4
    

    数据规模及约定

    对于 (100\%) 的数据,(0 < c_i le p le 10); (0 < u_i,v_i,d_i le n le 1000); (0 le m le 3000); (0 le w_i le 20000)

    题解

    斯坦纳树,后面再搞一次 dp,都比较简单。

    斯坦纳树可以去看这篇

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    #include <queue>
    using namespace std;
    #define rep(i, s, t) for(int i = (s); i <= (t); i++)
    #define dwn(i, s, t) for(int i = (s); i >= (t); i--)
    
    const int BufferSize = 1 << 16;
    char buffer[BufferSize], *Head, *Tail;
    inline char Getchar() {
    	if(Head == Tail) {
    		int l = fread(buffer, 1, BufferSize, stdin);
    		Tail = (Head = buffer) + l;
    	}
    	return *Head++;
    }
    int read() {
    	int x = 0, f = 1; char c = Getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
    	return x * f;
    }
    
    #define maxn 1010
    #define maxp 15
    #define maxm 6010
    #define maxs 1024
    #define oo 2147483647
    
    int n, m, p, head[maxn], nxt[maxm], to[maxm], dist[maxm], col[maxp];
    
    void AddEdge(int a, int b, int c) {
    	to[++m] = b; dist[m] = c; nxt[m] = head[a]; head[a] = m;
    	swap(a, b);
    	to[++m] = b; dist[m] = c; nxt[m] = head[a]; head[a] = m;
    	return ;
    }
    
    #define D f[Set]
    struct Node {
    	int u, d;
    	Node() {}
    	Node(int _, int __): u(_), d(__) {}
    	bool operator < (const Node& t) const { return d > t.d; }
    };
    priority_queue <Node> Q;
    int f[maxs][maxn];
    bool vis[maxn];
    void ShortPath(int Set) {
    	memset(vis, 0, sizeof(vis));
    	rep(i, 1, n) if(D[i] < oo) Q.push(Node(i, D[i]));
    	while(!Q.empty()) {
    		int u = Q.top().u; Q.pop();
    		if(vis[u]) continue;
    		vis[u] = 1;
    		for(int e = head[u]; e; e = nxt[e]) if(D[to[e]] > D[u] + dist[e]) {
    			D[to[e]] = D[u] + dist[e];
    			if(!vis[to[e]]) Q.push(Node(to[e], D[to[e]]));
    		}
    	}
    	return ;
    }
    
    int F[maxs], ans[maxs];
    
    int main() {
    	n = read(); int M = read(); p = read();
    	rep(i, 1, M) {
    		int a = read(), b = read(), c = read();
    		AddEdge(a, b, c);
    	}
    	
    	int all = (1 << p) - 1;
    	rep(s, 0, all) rep(i, 1, n) f[s][i] = oo;
    	rep(i, 0, p - 1) {
    		col[i] = read();
    		f[1<<i][read()] = 0;
    	}
    	rep(s, 0, all) {
    		rep(i, 1, n)
    			for(int ts = (s - 1 & s); ts; ts = (ts - 1 & s))
    				f[s][i] = min(f[s][i], f[ts][i] + f[s^ts][i]);
    		ShortPath(s);
    	}
    	
    	rep(s, 0, all) {
    		F[s] = oo;
    		rep(i, 1, n) F[s] = min(F[s], f[s][i]);
    	}
    	rep(s, 0, all) {
    		ans[s] = F[s];
    		for(int ts = (s - 1 & s); ts; ts = (ts - 1 & s)) {
    			int Col = 0, Cor = 0;
    			rep(i, 0, p - 1)
    				if(ts >> i & 1) Col |= (1 << col[i] - 1);
    				else Cor |= (1 << col[i] - 1);
    			if(Col & Cor) continue;
    			ans[s] = min(ans[s], F[ts] + F[s^ts]);
    		}
    	}
    	
    	printf("%d
    ", ans[all]);
    	
    	return 0;
    }
    
  • 相关阅读:
    前端开发聚合
    6. webRTC
    14.移动端图片浏览组件 react-wx-images-viewer
    windows下怎样使用md命令一次建立多级子目录
    mysql打印输出转csv格式
    Java Stream简介, 流的基本概念
    Linux使用Shell脚本实现ftp的自动上传下载
    在Linux中设置UMASK值
    SFTP+OpenSSH+ChrootDirectory设置
    导出php5.4支持的数组格式,即以[]为标识符而不是以array()标识
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/7999355.html
Copyright © 2011-2022 走看看