• Google Kick Start 2018 Round C Planet Distance


    思想:

    1、用邻接表建图。

    2、建完图之后,先把图中的环给找出来。

      怎么找呢?

         (1)先统计每一个节点的度。

       (2)统计完了之后,通过使用队列,把度为1 的点给剔除。每剔除一个,所谓剔除其实就是用一个dis[] 数组来做标记,其相应的邻居的度减一,如果该邻居的度为1了,那么把它加到队列里,重复上述过程,直到队列为空。

      (3)最后统计一下,剩下的就是环里的元素。

    3、再对环里的元素用BFS搞一下,往外扩散。记录距离。

    AC 代码如下:

    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.Queue;
    import java.util.Scanner;
    
    /**
     * @program: Leetcode
     * @description:
     * @author: Wangky
     * @create: 2019-09-15 15:05
     **/
    public class Solution {
    
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int T = sc.nextInt();
            int time = 1;
            while ((time )<= T){
                int n = sc.nextInt(); //  n 个顶点
                // construct a graph
                // 邻接表
                ArrayList<Integer> adj[] = new ArrayList[n+1];
                for (int i=0;i<adj.length;i++){
                    adj[i] = new ArrayList<>();
                }
                for(int i=0;i<n;i++){
                    int x = sc.nextInt();
                    int y = sc.nextInt();
                    adj[x].add(y);
                    adj[y].add(x);
                }
    
                // compute the degree of each node
                int[] degree = new int[n+1];
                Queue<Integer> q = new LinkedList<>();
                for(int i=1;i<=n;i++){
                    degree[i] = adj[i].size();
                    if (degree[i] == 1){
    
                        // 度为1的点(即只有一条边),入队列
                        ((LinkedList<Integer>) q).push(i);
                    }
                }
    
                int[] dis = new int[n+1];
                // Topological sort
                while (!q.isEmpty()){
                    int node = q.peek();
                    q.poll();
    
                    dis[node] = -1; // 代表该node节点不在环里,可以剔除掉,用 -1 做一个标记
    
                    // 节点node 的所有邻接点的度减1
                    for(int i=0;i<adj[node].size();i++){
                        int v = adj[node].get(i);
                        degree[v]--;
                        if (degree[v] == 1){
                            q.offer(v);
                        }
                    }
                }
    
                // Add node in the cycle
                // 复用该 queue
                //  从环里往外bfs
                for(int i=1;i<=n;i++){
                    if (dis[i] == 0){
                        q.offer(i);
                    }
                }
    
                while (!q.isEmpty()){
                    int node = q.peek();
                    q.poll();
                    for(int i=0;i<adj[node].size();i++){
                        int v=adj[node].get(i);
                        if (dis[v] == -1){
                            // 如果该节点在环外
                            dis[v] = dis[node]+1;
                            q.offer(v);
                        }
                    }
                }
    
                System.out.print("Case #"+time+": ");
                for(int i=1;i<=n;i++){
                    System.out.print(dis[i] + " ");
                }
                System.out.println();
                time++;
    
            }
        }
    
    
    }
  • 相关阅读:
    USACO2.2 Preface Numbering【思维+打表】
    USACO2.1 Hamming Codes【枚举+二进制处理+输出格式+题意理解】
    USACO1.6 Healthy Holsteins【dfs/bfs 爆搜】
    USACO1.5 Mother's Milk【搜索】
    USACO1.6 Number Triangles [dp-简单dp]
    USACO1.6 回文质数 Prime Palindromes
    泛型简介
    涉及 C#的 foreach问题
    c#委托事件及其讲解
    WPF 打印 包括设置,打印预览,打印等等
  • 原文地址:https://www.cnblogs.com/vector11248/p/11523590.html
Copyright © 2020-2023  润新知