|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 zhangjinxuan 于 2022-11-20 19:43 编辑
原题链接:
https://atcoder.jp/contests/abc277/tasks/abc277_e
原题翻译:
来源于:https://www.luogu.com.cn/problem/AT_abc277_e
题面
给定一张 n 个点 m 条边的无向图,每条边有一个权值 w (0 <= w <= 1), w = 0 表示无法通过,反之表示可通过
其中,有 k 个点上面有按钮,按下按钮,全部路的边权取反,即:w = 0 变成 1,w = 1 变成 0
你现在位于 1 号点,每次,你可以做两件事:
1. 移动到相邻的一个点上,前提是边可以通行;
2. 按按钮,前提是所在的点上有按钮
输入格式
第一行一个整数 n, m, k
接下来 m 行,每行三个数 u, v, w, 表示一条链接 u 与 v 的边,权值为 w
最后一行 k 个数,表示按钮的位置
输出格式
一个整数,表示最少移动步数,若无法到达,输出 -1
输入样例
- 5 5 2
- 1 3 0
- 2 3 1
- 5 4 1
- 2 1 1
- 1 4 0
- 3 4
复制代码
输出样例
我的代码
- #include <bits/stdc++.h>
- using namespace std;
- struct Info {
- int x;
- bool y;
- } q[501001];
- int n, m, k, u, v, s[200001], front, rear, step[200001][2];
- bool in_s[200001];
- bool a;
- vector<Info> edges[200001];
- void bfs() {
- memset(step, 255, sizeof(step));
- rear = front = 1;
- q[rear] = {1, 0};
- step[1][0] = 0;
- while (rear + 1 != front) {
- Info f = q[front++];
- //printf("%d %d : ", f.x, f.y);
- if (f.x == n) {
- if (step[f.x][0] == -1) printf("%d", step[f.x][1]);
- else if (step[f.x][1] == -1) printf("%d", step[f.x][0]);
- else printf("%d", min(step[f.x][0], step[f.y][1]));
- return;
- }
- for (Info i : edges[f.x]) {
- if (((f.y == 1 && i.y == 0) || (f.y == 0 && i.y == 1)) && step[i.x][0] == -1) {
- step[i.x][0] = step[f.x][f.y] + 1;
- q[++rear] = {i.x, 0};
- //printf("(OK)");
- } else if (in_s[f.x] && step[i.x][1] == -1) {
- step[i.x][1] = step[f.x][f.y] + 1;
- q[++rear] = {i.x, 1};
- }
- }
- }
- printf("-1");
- }
- int main() {
- scanf("%d%d%d", &n, &m, &k);
- for (int i = 1; i <= m; ++i) {
- scanf("%d%d%d", &u, &v, &a);
- edges[u].push_back({v, a});
- edges[v].push_back({u, a});
- }
- for (int i = 1; i <= k; ++i) {
- scanf("%d", &s[i]);
- in_s[s[i]] = 1;
- }
- bfs();
- return 0;
- }
复制代码
不知道是思路错了还是细节错了,希望大佬给予解答
|
|