• Codeforces 1149D 最短路 状压DP


    题意及思路:https://blog.csdn.net/yzyyylx/article/details/90145400

    这题主要巧妙在分析了最短路算法的性质,得出大小小于等于3的连通块一定不会被再次访问的结论。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    bool v[80][1 << 18];
    int dp[80][1 << 18];
    const int maxn = 1010;
    struct node {
    	int dis, state, now;
    	bool operator < (const node& rhs) const {
    		return dis > rhs.dis;
    	}
    };
    struct Edge {
    	int v, w;
    };
    vector<Edge> G[maxn];
    int sz[maxn], num[maxn], ans[maxn];
    int A, B, n, m, tot;
    void add(int x, int y, int z) {
    	G[x].push_back((Edge){y, z});
    	G[y].push_back((Edge){x, z});
    }
    priority_queue<node> q;
    int f[maxn];
    int get(int x) {
    	if(x == f[x]) return x;
    	return f[x] = get(f[x]);
    }
    void merge(int x, int y) {
    	int x1 = get(x), y1 = get(y);
    	if(x1 == y1) return;
    	f[x1] = y1;
    	sz[y1] += sz[x1];
    }
    int get_num(int x) {
    	if(sz[get(x)] > 3)
    		return 1 << num[get(x)];
    	else
    		return 0;
    }
    void dijkstra() {
    	memset(dp, 0x3f, sizeof(dp));
    	memset(ans, 0x3f, sizeof(ans));
    	q.push((node){0, get_num(1), 1});
    	dp[1][get_num(1)] = 0;
    	while(!q.empty()) {
    		node tmp = q.top();
    		q.pop();
    		if(v[tmp.now][tmp.state]) continue;
    		v[tmp.now][tmp.state] = 1;
    		ans[tmp.now] = min(ans[tmp.now], tmp.dis);
    		for (auto x : G[tmp.now]) {
    			if(x.w == B && get(x.v) == get(tmp.now)) continue;
    			if(x.w == B && (tmp.state & get_num(x.v))!= 0) continue;
    			if(x.w + tmp.dis < dp[x.v][get_num(x.v) | tmp.state]) {
    				dp[x.v][get_num(x.v) | tmp.state] = x.w + tmp.dis;
    				q.push((node){dp[x.v][get_num(x.v) | tmp.state], get_num(x.v) | tmp.state, x.v});
    			}
    		}
    	}
    }
    int main() {
    	int x, y, z;
    	scanf("%d%d%d%d", &n, &m, &A, &B);
    	for (int i = 1; i <= n; i++) {
    		f[i] = i;
    		sz[i] = 1;
    	}
    	for (int i = 1; i <= m; i++) {
    		scanf("%d%d%d", &x, &y, &z);
    		add(x, y, z);
    		if(z == A) {
    			merge(x, y);
    		}
    	}
    	for (int i = 1; i <= n; i++) {
    		if(i == get(i) && sz[i] > 3) {
    			num[i] = tot++;
    		}
    	}
    	dijkstra();
    	for (int i = 1; i <= n; i++)
    		printf("%d ", ans[i]);
    }
    

      

  • 相关阅读:
    洛谷 P2922 [USACO08DEC]秘密消息Secret Message
    HDU 1542 Atlantis
    洛谷 P2146 软件包管理器
    rabbitmq
    POJ——T2446 Chessboard
    洛谷—— P3375 【模板】KMP字符串匹配
    洛谷——P3370 【模板】字符串哈希
    POJ——T1860 Currency Exchange
    洛谷—— P3386 【模板】二分图匹配
    python(1)- 初识python
  • 原文地址:https://www.cnblogs.com/pkgunboat/p/10933048.html
Copyright © 2020-2023  润新知