• 【LG4294】[WC2008]游览计划


    【LG4294】[WC2008]游览计划

    题面

    洛谷

    bzoj

    题解

    斯坦纳树板子题。

    斯坦纳树的总结先留个坑。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring> 
    #include <cmath> 
    #include <algorithm>
    #include <queue> 
    using namespace std; 
    inline int gi() {
    	register int data = 0, w = 1;
    	register char ch = 0;
    	while (!isdigit(ch) && ch != '-') ch = getchar(); 
    	if (ch == '-') w = -1, ch = getchar();
    	while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar();
    	return w * data; 
    } 
    typedef pair<int, int> P; 
    typedef pair<P, int> Pi;
    #define fi first
    #define se second
    const int INF = 0x3f3f3f3f; 
    int N, M, K, rt, f[105][1111], a[105], ans[15][15]; 
    bool inq[105]; 
    Pi pre[105][1111]; 
    const int dx[] = {0, 0, -1, 1} ; 
    const int dy[] = {1, -1, 0, 0} ; 
    queue<P> que; 
    bool check(P x) { return x.fi >= 0 && x.se >= 0 && x.fi < N && x.se < M; } 
    #define num(u) (u.fi * M + u.se) 
    void spfa(int o) {
    	while (!que.empty()) {
    		P x = que.front(); que.pop(); inq[num(x)] = 0; 
    		for (int i = 0; i < 4; i++) {
    			P v = make_pair(x.fi + dx[i], x.se + dy[i]); 
    			int nx = num(x), nv = num(v); 
    			if (check(v) && f[nv][o] > f[nx][o] + a[nv]) {
    				f[nv][o] = f[nx][o] + a[nv]; 
    				if (!inq[nv]) inq[nv] = 1, que.push(v); 
    				pre[nv][o] = make_pair(x, o); 
    			} 
    		} 
    	} 
    }
    void dfs(P x, int o) {
    	if (!pre[num(x)][o].se) return ; 
    	ans[x.fi][x.se] = 1; 
    	int nx = num(x); 
    	if (pre[nx][o].fi == x) dfs(x, o ^ pre[nx][o].se);
        dfs(pre[nx][o].fi, pre[nx][o].se);
    } 
    int main () {
    #ifndef ONLINE_JUDGE 
    	freopen("cpp.in", "r", stdin); 
    #endif 
    	cin >> N >> M; 
    	memset(f, 0x3f, sizeof(f)); 
    	for (int i = 0, tot = 0; i < N; i++) {
    		for (int j = 0; j < M; j++) { 
    			cin >> a[tot]; 
    			if (!a[tot]) f[tot][1 << (K++)] = 0, rt = tot; 
    			++tot; 
    		} 
    	}
    	for (int o = 1; o < (1 << K); o++) {
            for (int i = 0; i < N * M; i++) {
                for (int s = o & (o - 1); s; s = o & (s - 1)) 
    				if (f[i][o] > f[i][s] + f[i][o ^ s] - a[i]) {
    					f[i][o] = f[i][s] + f[i][o ^ s] - a[i];
    					pre[i][o] = make_pair(make_pair(i / M, i % M), s);
    				} 
                if (f[i][o] < INF) que.push(make_pair(i / M, i % M)), inq[i] = 1;
    		}
    		spfa(o);
        }
    	cout << f[rt][(1 << K) - 1] << endl; 
        dfs(make_pair(rt / M, rt % M), (1 << K) - 1);
        for (int i = 0, tot = 0; i < N; i++){
    		for (int j = 0; j < M; j++)
    			if (!a[tot++]) putchar('x');
    			else putchar(ans[i][j] ? 'o' : '_');
    		printf("
    "); 
        }
    	return 0; 
    } 
    
  • 相关阅读:
    机器学习第二章复习
    机器学习第三章复习
    机器学习第四章复习
    第一次作业
    第二次作业
    第06组 Beta版本演示
    第06组 Beta冲刺(4/4)
    第06组 Beta冲刺(3/4)
    第06组 Beta冲刺(2/4)
    第06组 Beta冲刺(1/4)
  • 原文地址:https://www.cnblogs.com/heyujun/p/10325124.html
Copyright © 2020-2023  润新知