AtCoder Beginner Contest 277 E - Crystal Switches(最短路)

pokemon朱紫偷跑,(主要是调环境,弄了好久,下午才玩上,A卡太惨了)打了一天,有点懈怠。最后8:30才吃完饭,就慢慢写了

题意:

给你n个点, m m m条边.
每条边有初始状态 a [ i ] a[i] a[i] a [ i ] = 0 a[i] = 0 a[i]=0表示不可以通过, a [ i ] = 1 a[i] = 1 a[i]=1表示可以通过。

  • k k k个点有开关,
  • 在有开关的点上,可以将所有边的状态改变。

走最少步,从1 → \rightarrow n

思路:

d p [ x ] [ 0 / 1 ] dp[x][0/1] dp[x][0/1]表示这个点的状态
之后跑bfs就行了,边权为1.

笔者,赛时,跑了最短路。。

AC

package com.hgs.atcoder.abc.contest277.e;

/**
 * @author youtsuha
 * @version 1.0
 * Create by 2022/11/12 19:58
 */

import java.util.*;
import java.io.*;
public class Main {
    static FastScanner cin;
    static PrintWriter cout;
    static int [][] dp;
    private static void init()throws IOException {
        cin = new FastScanner(System.in);
        cout = new PrintWriter(System.out);
    }

    private static void close(){
        cout.close();
    }
    static int n, m, k;
    static class node{
        int a, b, c;
        //[]
        public node(int a, int b, int c) {
            this.a = a;
            this.b = b;
            this.c = c;
        }
    }
    static List<node> e[];
    static int ans = (int) 1e9;
    static int inf = (int) 1e9;
    static boolean isSwitch[];
//    static boolean dfs(int x, int fa, int rot, int dep){
//
//    }
    private static void sol()throws IOException {
        n = cin.nextInt(); m = cin.nextInt(); k = cin.nextInt();
        dp = new int[n][2];
//        Arrays.fill(dp[0],inf);
//        Arrays.fill(dp[1],inf);
        for(int j = 0; j < 2; j ++ ) {
            for(int i = 0; i < n; i ++ ){
                //cout.print(dp[i][j] + " ");
                dp[i][j] = inf;
            }
//            cout.println("");
        }
        e = new ArrayList[n];
        isSwitch = new boolean[n];
        for(int i = 0; i < n; i ++ ) {
            e[i] = new ArrayList<>();
        }
        for(int i = 0; i < m; i ++ ) {
            int a = cin.nextInt(), b = cin.nextInt(), c = cin.nextInt();
            a--; b--;
            e[a].add(new node(b,c,0));
            e[b].add(new node(a,c,0));
        }
        for(int i = 0; i < k; i ++ ) {
            int x = cin.nextInt(); x--;
            isSwitch[x] = true;
        }
//        dfs(0,-1,0, 0);
        PriorityQueue<node> que = new PriorityQueue<>((a,b)->a.c - b.c);
        dp[0][0] = 0;
        que.add(new node(0,0,0));
        while(!que.isEmpty()){
            int x = que.peek().a, d = que.peek().c, rot=  que.peek().b;
            que.poll();
            if(dp[x][rot] > d) {
                continue;
            }
            for(int i = 0; i < e[x].size(); i ++ ) {
                int v = e[x].get(i).a, p = e[x].get(i).b;
                int nxt = (p + rot) % 2;
                if(nxt % 2 == 1){
                    if(dp[v][rot] > d + 1){
                        dp[v][rot] = Math.min(dp[v][rot], d + 1);
                        que.add(new node(v,rot,d+1));
                    }
                }else if(isSwitch[x]){
                    nxt = (rot + 1) % 2;
                    if(dp[v][nxt] > d + 1){
                        dp[v][nxt] = Math.min(dp[v][nxt], d + 1);
                        que.add(new node(v,nxt, d + 1));
                    }
                }
            }
        }
        int ans = inf;
        if(dp[n-1][0] != inf) {
            ans = Math.min(ans, dp[n-1][0]);
        }if(dp[n-1][1] != inf) {
            ans = Math.min(ans, dp[n-1][1]);
        }
        if(ans == inf) {
            cout.println(-1);
        }else {
            cout.println(ans);
        }
    }
    public static void main(String[] args) throws IOException {
        init();
        sol();
        close();
    }
}
class FastScanner {
    BufferedReader br;
    StringTokenizer st = new StringTokenizer("");

    public FastScanner(InputStream s) {
        br = new BufferedReader(new InputStreamReader(s));
    }

    public FastScanner(String s) throws FileNotFoundException {
        br = new BufferedReader(new FileReader(new File(s)));
    }

    public String next() throws IOException {
        while (!st.hasMoreTokens()){
            try {
                st = new StringTokenizer(br.readLine());
            } catch (IOException e) { e.printStackTrace(); }
        }
        return st.nextToken();
    }

    public int nextInt() throws IOException {
        return Integer.parseInt(next());
    }

    public long nextLong() throws IOException {
        return Long.parseLong(next());
    }

    public double nextDouble() throws IOException {
        return Double.parseDouble(next());
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值