首页 > 其他分享 >HDU - 7187-Slipper

HDU - 7187-Slipper

时间:2023-09-05 10:56:42浏览次数:35  
标签:HDU int cin Slipper dep add maxdep 7187 dis

HDU - 7187-Slipper (最短路、建图优化)

题意:

给出n个结点,n-1条无向边,经过每条边的代价为w,以结点1为根节点的树,对于相差k层的结点,可以花费代价p抵达,问结点st的最短路径。

分析:

考虑对于每层的每个点建立到相差k层的点的边,极端情况为 $O(n^2)$ 的复杂度,需要优化。

考虑对于每层额外添加点。层与层之间的边通过虚点连接,代价为p

若只添加一个点,则该点到这一层的点必须是双向的,但这样会使同层之间可以直接抵达。错解。

考虑添加两个点,一个点(a)建立该层的点到a的单向边,代价为0,另一个点(b)建立b到该层的点的单向边,代价为0。层与层之间的边连接如下图所示:

解题步骤:

由上分析知,先正常建图,然后dfs出图的深度,同时添加每一层的点到虚点的边。跑一遍迪杰斯特拉即可。

邻接表:

const int N = 1e6 + 10;
const ll INF = 0x3f3f3f3f3f3f3f3f;
struct node {
	int v; int w;
};

int n; 
vector<node>g[N * 3];
int dep[N], maxdep = 0;
ll dis[N * 3];
int vis[N * 3];
priority_queue<pair<ll, int>>q;

void init(int n) {
	for (int i = 0; i <= n; i++) {
		g[i].clear(), g[i + n].clear(), g[i + n * 2].clear();
		dis[i] = INF, dis[i + n] = INF, dis[i + n * 2] = INF;
		vis[i] = 0, vis[i + n] = 0, vis[i + n * 2] = 0;
		dep[i] = 0;
	}
	maxdep = 0;
}

void add(int u, int v, int w) {
	g[u].push_back({ v,w });
}

void dfs(int u, int f) {
	dep[u] = dep[f] + 1;
	maxdep = max(maxdep, dep[u]);
	for (auto it : g[u]) {
		int v = it.v;
		if (v == f)continue;
		dfs(v, u);
	}
	add(u, dep[u] + n, 0);
	add(dep[u] + n * 2, u, 0);
}

void dij(int s) {
	dis[s] = 0;
	q.push({ 0,s });
	while (q.size()) {
		auto it = q.top(); q.pop();
		int u = it.second; if (vis[u])continue;
		vis[u] = 1;
		for (auto t : g[u]) {
			int v = t.v, w = t.w;
			if (dis[v] > dis[u] + w) {
				dis[v] = dis[u] + w;
				q.push({ -dis[v],v });
			}
		}
	}
}

void solve() {
	cin >> n;
	init(n);
	for (int i = 1; i < n; i++) {
		int u, v, w; cin >> u >> v >> w;
		add(u, v, w);
		add(v, u, w);
	}
	int k, p; cin >> k >> p;
	int s, t; cin >> s >> t;
	dfs(1, 0);
	for(int i = 1; i <= n; i++) {
		if (i + k > maxdep)break;
		add(i + n, i + k + n * 2, p);
		add(i + k + n, i + n * 2, p);
	}
	dij(s);
	cout << dis[t] << endl;
}

链式前向星:

struct node {
	int v, ne;
	ll w;
}e[N * 4];
int h[N * 4], idx;
int dep[N * 2], maxdep;
ll dis[N * 4];
int vis[N * 4];
priority_queue<pair<ll, int>>q;
int n; 

void add(int u, int v, int w) {
	e[idx] = { v,h[u],w };
	h[u] = idx++;
}

void dfs(int u, int f) {
	dep[u] = dep[f] + 1;
	maxdep = max(maxdep, dep[u]);
	for (int i = h[u]; i != -1; i = e[i].ne) {
		int v = e[i].v;
		if (v == f)continue;
		dfs(v, u);
	}
	add(u, dep[u] + n, 0);
	add(dep[u] + n * 2, u, 0);
}

void solve() {
	cin >> n;
	memset(h, -1, sizeof h);
	idx = 0;
	maxdep = 0;
	for (int i = 1; i < n; i++) {
		int u, v, w; cin >> u >> v >> w;
		add(u, v, w);
		add(v, u, w);
	}
	dfs(1, 0);

	int k, p; cin >> k >> p;
	for (int i = 1; i <= maxdep; i++) {
		if (i + k > maxdep)break;
		add(i + n, i + k + n * 2, p);
		add(i + k + n, i + n * 2, p);
	}
	for (int i = 0; i <= n; i++) {
		dis[i] = INF, dis[i + n] = INF, dis[i + n * 2] = INF;
		vis[i] = 0, vis[i + n] = 0, vis[i + n * 2] = 0;
	}
	int s, t; cin >> s >> t;
	dis[s] = 0;
	q.push({ 0,s });
	while (q.size()) {
		auto it = q.top(); q.pop();
		int u = it.second; if (vis[u])continue;
		vis[u] = 1;
		for (int i = h[u]; i != -1; i = e[i].ne) {
			int v = e[i].v; ll w = e[i].w;
			if (dis[v] > dis[u] + w) {
				dis[v] = dis[u] + w;
				q.push({ -dis[v], v });
			}
		}
	}
	cout << dis[t] << endl;
}

标签:HDU,int,cin,Slipper,dep,add,maxdep,7187,dis
From: https://www.cnblogs.com/yxyxyxyxyx/p/17679066.html

相关文章

  • HDU - 2844 - coins
    HDU-2844-coins(多重背包)题意:大壮想买东西,他有n种不同面值的硬币,每种有$c_i$个,他不想找零,也不想买超过价值m的东西,问他有多少种支付方式。$n(1≤n≤100),m(m≤100000)$分析:可以发现m的范围不大,直接在m中遍历。转化为给定一个容量为m的背包,问装入不同方案时,不同......
  • 代码(待加解释) hdu2196
    #include<bits/stdc++.h>usingnamespacestd;constintmaxn=3e4+10;#definelllonglonginthead[maxn],ver[maxn],nxt[maxn],edge[maxn];inttot;llf[maxn][3];intrx[maxn];voiddfs1(intx,intfa){  for(inti=head[x];i;i=nxt[i])  {   ......
  • hdu:Machine Schedule(二分图匹配)
    ProblemDescriptionAsweallknow,machineschedulingisaveryclassicalproblemincomputerscienceandhasbeenstudiedforaverylonghistory.Schedulingproblemsdifferwidelyinthenatureoftheconstraintsthatmustbesatisfiedandthetypeof......
  • hdu:Oil Deposits(dfs连通图)
    ProblemDescriptionTheGeoSurvCompgeologicsurveycompanyisresponsiblefordetectingundergroundoildeposits.GeoSurvCompworkswithonelargerectangularregionoflandatatime,andcreatesagridthatdividesthelandintonumeroussquareplots.......
  • hdu:手机的诱惑(dfs+剪枝)
    ProblemDescription张晨乐在一个古老的迷宫中发现了一个手机,这个手机深深地吸引了他。然而,当他拾起手机,迷宫开始摇晃,张晨乐能感觉到地面下沉。他意识到:这个手机只是一个诱饵!于是,他不顾一切地试图冲出这个迷宫。迷宫是一个大小为N*M的矩形,有一扇门,一开始,门是关闭的,并在第T秒打......
  • hdu:Rescue(bfs+优先队列)
    ProblemDescriptionAngelwascaughtbytheMOLIGPY!HewasputinprisonbyMoligpy.TheprisonisdescribedasaN*M(N,M<=200)matrix.ThereareWALLs,ROADs,andGUARDsintheprison.Angel’sfriendswanttosaveAngel.Theirtaskis:approach......
  • hdu:Knight Moves(bfs)
    ProblemDescriptionAfriendofyouisdoingresearchontheTravelingKnightProblem(TKP)whereyouaretofindtheshortestclosedtourofknightmovesthatvisitseachsquareofagivensetofnsquaresonachessboardexactlyonce.Hethinksthatthe......
  • hdu:A strange lift(bfs)
    ProblemDescriptionThereisastrangelift.Theliftcanstopcanateveryfloorasyouwant,andthereisanumberKi(0<=Ki<=N)oneveryfloor.Thelifthavejusttwobuttons:upanddown.Whenyouatfloori,ifyoupressthebutton“UP”,youwi......
  • hdu:一个人的旅行
    ProblemDescription虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中会遇见很多人(白马王子,0),很多事,还能丰富自己的阅历,还可以看美丽的风景……草儿想去很多地方,她想要去东京铁塔看夜景,去威尼斯看电影,去阳明山上看海芋,去纽......
  • hdu:悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
    ProblemDescription急!灾区的食物依然短缺!为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品,其价格不等,并且只能整袋购买。请问:你用有限的资金最多能采购多少公斤粮食呢?后记:人生是一个充满了......