首页 > 其他分享 >CodeForces 1149D Abandoning Roads

CodeForces 1149D Abandoning Roads

时间:2023-09-23 16:25:55浏览次数:52  
标签:连通 int ll 1149D typedef long Roads Abandoning 轻边

洛谷传送门

CF 传送门

考虑一条 \(1 \to i\) 的路径是否在最小生成树上。

称边权为 \(a\) 的边为轻边,边权为 \(b\) 的边为重边。

轻边若不成环则一定在最小生成树上,因此先把轻边合并,这样形成了若干连通块。

那么如果两点在一个连通块,它们只能通过轻边互达。

同时,因为是树上路径,所以不会走出一个连通块再走回这个连通块。

于是可以想到设 \(f_{S, u}\) 为当前已经经过的连通块集合,和当前所在的点。

因为 \(f_{S, u}, f_{S, v}\) 可以互相转移,所以用最短路的方式计算。

但是有个问题。连通块个数可能很多,无法状压。

但是注意到,若连通块点数 \(\le 3\),那么任意两点都能通过不超过两条轻边互达,所以通过重边走出去再走回来一定不优。所以就可以直接不记录这些连通块。

那么因为要记录的连通块点数 \(\ge 4\),所以连通块个数 \(\le \frac{n}{4}\)。

所以复杂度就变成了 \(O(2^{\frac{n}{4}} m \log (2^{\frac{n}{4}} m))\)。

code
// Problem: D. Abandoning Roads
// Contest: Codeforces - Codeforces Round 556 (Div. 1)
// URL: https://codeforces.com/problemset/problem/1149/D
// Memory Limit: 512 MB
// Time Limit: 5000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 210;
const int maxm = (1 << 17) + 50;

ll n, m, A, B, fa[maxn], tot, id[maxn], sz[maxn];
ll f[maxm][75];
vector<pii> G[maxn];

int find(int x) {
	return fa[x] == x ? x : fa[x] = find(fa[x]);
}

inline void merge(int x, int y) {
	x = find(x);
	y = find(y);
	if (x != y) {
		fa[x] = y;
		sz[y] += sz[x];
	}
}

struct node {
	ll S, u, d;
	node(ll a = 0, ll b = 0, ll c = 0) : S(a), u(b), d(c) {}
};

bool vis[maxm][75];

inline bool operator < (const node &a, const node &b) {
	return a.d > b.d;
}

void solve() {
	scanf("%lld%lld%lld%lld", &n, &m, &A, &B);
	for (int i = 1; i <= n; ++i) {
		fa[i] = i;
		sz[i] = 1;
	}
	while (m--) {
		ll u, v, d;
		scanf("%lld%lld%lld", &u, &v, &d);
		G[u].pb(v, d);
		G[v].pb(u, d);
		if (d == A) {
			merge(u, v);
		}
	}
	for (int i = 1; i <= n; ++i) {
		if (fa[i] == i) {
			if (sz[i] > 3) {
				id[i] = tot++;
			} else {
				id[i] = -1;
			}
		}
	}
	for (int i = 1; i <= n; ++i) {
		id[i] = id[find(i)];
	}
	mems(f, 0x3f);
	f[id[1] == -1 ? 0 : (1 << id[1])][1] = 0;
	priority_queue<node> pq;
	pq.emplace(id[1] == -1 ? 0 : (1 << id[1]), 1, 0);
	while (pq.size()) {
		int S = pq.top().S, u = pq.top().u;
		pq.pop();
		if (vis[S][u]) {
			continue;
		}
		vis[S][u] = 1;
		for (pii p : G[u]) {
			ll v = p.fst, d = p.scd;
			if (id[v] != -1 && id[u] != id[v] && (S & (1 << id[v]))) {
				continue;
			}
			if (find(u) == find(v) && d == B) {
				continue;
			}
			int T = S | (id[v] == -1 ? 0 : 1 << id[v]);
			if (f[T][v] > f[S][u] + d) {
				f[T][v] = f[S][u] + d;
				if (!vis[T][v]) {
					pq.emplace(T, v, f[T][v]);
				}
			}
		}
	}
	for (int i = 1; i <= n; ++i) {
		ll ans = 9e18;
		for (int S = 0; S < (1 << tot); ++S) {
			ans = min(ans, f[S][i]);
		}
		printf("%lld ", ans);
	}
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:连通,int,ll,1149D,typedef,long,Roads,Abandoning,轻边
From: https://www.cnblogs.com/zltzlt-blog/p/17724542.html

相关文章

  • CF671D Roads in Yusland
    1D8ya。设\(f_{u,i}\)表示覆盖了\(u\)子树并且向上覆盖到了深度为\(i\)的最小代价。考虑合并儿子\(v\):\[f'_{u,i}\gets\min\left(f_{u,i}+\min\limits_{j=1}^nf_{v,j},f_{v,i}+\min\limits_{j=1}^nf_{u,j}\right)\]相当于区间加,单点取\(\min\),区间求最小值。直接......
  • Roads in the North POJ - 2631 - 树的直径/树形dp
    题意:给出一棵无向树,求树的直径,即树上两点之间的最长距离分析:两种解法解法1:先任取一个点,找到距离该点最远的点u,再找到距离u最远的点v,那么u和v之间的路径就是一条直径。证明:只要找到了树的直径的一个端点,再从该点找到最远点就一定是直径的另一个端点。所以只需要证明第一次找到的......
  • CF671D Roads in Yusland 题解
    题目链接题目要求我们求出选出若干条路径并最小化花费,如果这是在链上,我们可以考虑直接枚举每条路径的右端点dp,那树呢?把路径剖分整个覆盖的集合就不一定连续了,没法dp,况且题目里给了很强的条件:路径一定是从孩子到祖先,硬转链用不上这个性质,貌似不太对。上述思考启发我们利用树的......
  • Constructing Roads
    ConstructingRoadsTimeLimit:2000/1000MS(Java/Others)    MemoryLimit:65536/32768K(Java/Others)TotalSubmission(s):17199    AcceptedSubmission(s):6529ProblemDescriptionThereareNvillages,whicharenumberedfrom1toN,andyou......
  • P3008 [USACO11JAN]Roads and Planes G
    P3008[USACO11JAN]RoadsandPlanesG思路按照分连通块的方法进行计算,并且如果不是本连通块的点,不能在现在的本次dfs中求解最小值。要一个一个的联通快进行标记。/*不能直接走disj的话,缩点的思想很重要首先尽量不要使用spfa进行走图,可能会卡对道路进行求连通块,对航线求度数......
  • Codeforces Round #Pi (Div. 2) E. President and Roads (最短路+强连通求割边)
    题目地址:codeforces#pi(DIV2)E题目很水。。就是先求两边最短路,然后把可能为最短路的边挑出来,然后判断是否yes只需要转化成无向图跑一遍tarjan,找出割边,割边就是yes,然后剩下的边就让它的值为最短路-1就行了,如果-1后变成了非正数,就是no.但是!!!居然卡spfa!!那是不是说cf以后就不......
  • UVa 11723 Numbering Roads (water ver.)
    11723-NumberingRoadsTimelimit:1.000secondshttp://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=2823Inmycountry,streetsdon’thavenames,eachofthemarejustgivenanumber......
  • CF-25C - Roads in Berland(水题)
    C-RoadsinBerlandCrawlinginprocess...CrawlingfailedTimeLimit:2000MSMemoryLimit:262144KB64bitIOFormat:%I64d&%I64u​​Submit​​​......
  • CF-25D - Roads not only in Berland(并查集或者搜索)
    D-RoadsnotonlyinBerlandCrawlinginprocess...CrawlingfailedTimeLimit:2000MSMemoryLimit:262144KB64bitIOFormat:%I64d&%I64u​​Submit​​......
  • C - Roads and Libraries HackerRank - torque-and-development 【 并查集 】
    C-RoadsandLibraries HackerRank-torque-and-development 题意:给一堆点与点之间有没有边,在某一些地方建图书馆,最后让每个城市都可以到达有图书馆的地方,每个点......