CF 1725 - M. Moving Both Hands

https://codeforces.ml/problemset/problem/1725/M

题意

给你一张带边权的有向图,一只手在节点1,另一只手在第i个节点(2<=i<=n)每次可以移动一只手从当前节点到其子节点,花费的时间为边权,问两只手移到同一个节点要的最小时间,如果不存在输出-1。对于每个能去到的i都要输出答案。

思路

先正向建图然后再用另外n个点建一个原图的反向图,原图和反向图对应的点用一条边权的边相连,然后对整个图跑个最短路即可。

#include<bits/stdc++.h>
#include<iostream>
#include<vector>
#include<array>
#include<unordered_map>
#include<ctime>
#include<random>
#define ll long long
#define ull unsigned long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const ll inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-10;
const ll N = 2e5 + 5;
const ll M = 1e5 + 5;
const ll mod = 1e9 + 7;
int n, m;
ll dis[N], vis[N];
vector<pair<int, ll>>g[N];

void dij(int s) {
	priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>>q;
	for (int i = 1; i <= n + n; i++) dis[i] = INF;
	dis[s] = 0;
	q.push({ 0, s });
	while (!q.empty()) {
		auto now = q.top();
		q.pop();
		int x = now.second;
		if (vis[x]) continue;
		vis[x] = 1;
		for (auto it : g[x]) {
			int to = it.first;
			ll w = it.second;
			if (dis[to] > dis[x] + w) {
				dis[to] = dis[x] + w;
				q.push({ dis[to], to });
			}
		}
	}

}

void init() {
	for (int i = 1; i <= n; i++) {
		g[i].clear();
		vis[i] = 0;
	}
}

void solve() {
	cin >> n >> m;
	init();
	for(int i = 1; i <= n; i++) 
		g[i].push_back({ i + n, 0 });
	for (int i = 1, u, v, w; i <= m; i++) {
		cin >> u >> v >> w;
		g[u].push_back({ v, w });
		g[v + n].push_back({ u + n, w });
	}
	dij(1);
	for (int i = 2; i <= n; i++) {
		cout << (dis[i + n] >= INF ? -1 : dis[i + n]) << " \n"[i == n];
	}
}

signed main()
{
	IOS;
	int t = 1;
	//cin >> t;
	while (t--)
		solve();
}
posted @   Yaqu  阅读(141)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示