CF 1725 - M. Moving Both Hands
https://codeforces.ml/problemset/problem/1725/M
题意
给你一张带边权的有向图,一只手在节点1,另一只手在第i个节点()每次可以移动一只手从当前节点到其子节点,花费的时间为边权,问两只手移到同一个节点要的最小时间,如果不存在输出-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();
}
分类:
图论
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现