1. 程式人生 > >Codeforces - 20C & 115A & 840A & 782C

Codeforces - 20C & 115A & 840A & 782C

Codeforces - 20C & 115A & 840A & 782C


Codeforces - 20C - Dijkstra?

題目連結

題目大意

給你一個有權圖,求從頂點1到頂點n的最短路徑。
在這裡插入圖片描述

解析

Dijkstra模板

用一個pre陣列儲存是由哪個節點更新過來的就可以得到最短路徑。

import java.io.BufferedInputStream;
import java.util.*;

public class Main {

    static class Graph{

        public int n;
        public int m;
        public boolean[] vis;
        public ArrayList<Edge>g[];

        public Graph(int n) {
            this
.n = n; vis = new boolean[n]; g = new ArrayList[n]; for(int i = 0; i < n; i++){ vis[i] = false; g[i] = new ArrayList<>(); } } } static class Edge implements Comparable<Edge>{ public
int to; public int w; public Edge(int to, int w) { this.to = to; this.w = w; } @Override public int compareTo(Edge o) { return w - o.w; } } static int[] dijkstra(Graph G, int s, int[] pre){ PriorityQueue<Edge>pq = new PriorityQueue<>(); int[] dis = new int[G.n]; for(int i = 0; i < G.n; i++) dis[i] = Integer.MAX_VALUE; //初始標記(不是-1(因為是求最小的)) pq.add(new Edge(s, 0)); while(!pq.isEmpty()){ Edge curEdge = pq.poll(); int to = curEdge.to; if(G.vis[to]) continue; G.vis[to] = true; for(int i = 0; i < G.g[to].size(); i++){ int nxtNode = G.g[to].get(i).to; int nxtW = G.g[to].get(i).w; if(!G.vis[nxtNode] && dis[nxtNode] > dis[to] + nxtW){ dis[nxtNode] = dis[to] + nxtW; pre[nxtNode] = to; // only add this code pq.add(new Edge(nxtNode, dis[nxtNode])); } } } return dis; } public static void main(String[] args){ Scanner cin = new Scanner(new BufferedInputStream(System.in)); int n = cin.nextInt(); int m = cin.nextInt(); Graph G = new Graph(n); for(int i = 0; i < m; i++){ int from = cin.nextInt(); int to = cin.nextInt(); int w = cin.nextInt(); G.g[from-1].add(new Edge(to-1, w)); G.g[to-1].add(new Edge(from-1, w)); } int[] pre = new int[n]; Arrays.fill(pre, -1); int[] dis = dijkstra(G, 0, pre); if(dis[n-1] == Integer.MAX_VALUE){ System.out.println("-1"); return; } Stack<Integer>stack = new Stack<>(); int p = n-1; while(p != -1){ stack.push(p); p = pre[p]; } System.out.print(stack.pop()+1); while(!stack.isEmpty()) System.out.print(" " + (stack.pop()+1)); System.out.println(); } }

Codeforces - 115A - Party

題目連結

題目大意

給你n,代表有n個與員工,然後給你每個員工的直接上司是誰(所有人從1~n編號),要你將這n個人分成最少的組,要求: ①每個員工必須屬於某一個組;②一組內的任何兩個人直接不能是上下級關係(包括直接上下級和間接上下級);
在這裡插入圖片描述

解析

題目樣例:
在這裡插入圖片描述

思路很簡單:

  • 我們只需要求所有員工到他祖先的路徑長度中最長的那條的長度。因為沒一層都可以屬於一個組,即使有多個連通分量。
  • 可以使用和並查集類似的結構,儲存每個節點的父親節點。然後迭代查詢即可。

在這裡插入圖片描述

import java.io.BufferedInputStream;
import java.util.Scanner;

public class Main {

    static class UnionSet{
        public int[] parent;
        public UnionSet(int n) {
            parent = new int[n+1];
        }

        public int findRoot(int v){
            int len = 0; 
            while(parent[v] != v){
                v = parent[v];
                len++;
            }
            return len;
        }
    }

    public static void main(String[] args){

        Scanner cin = new Scanner(new BufferedInputStream(System.in));
        int n = cin.nextInt();
        UnionSet uset = new UnionSet(n);
        for(int i = 1; i <= n; i++){
            int num = cin.nextInt();
            if(num == -1)
                uset.parent[i] = i;
            else
                uset.parent[i] = num;
        }
        int res = -1;
        for(int i = 1; i <= n; i++)
            res = Math.max(res, uset.findRoot(i)); //最大的那個
        System.out.println(res+1);
    }
}


Codeforces - 840A - Leha and Function

題目連結

題目大意

給你一個函式F(n, k),意思是從1 ~ n裡選出 k 個數,每次的貢獻是選出的 k個數中最小的那個數。輸入n,陣列a、b要你將a陣列重新排列,使得F(ai, bi)的和最大。
在這裡插入圖片描述

解析

貪心,a陣列更大的要去匹配 b陣列更小的,這樣才會更大。

a陣列升序排列,b陣列降序排列並記錄之前的索引,最後遍歷將a陣列中元素放到正確的位置。

import java.io.BufferedInputStream;
import java.util.Arrays;
import java.util.Scanner;

public class Main {

    static class Pair{
        public int num;
        public int id;

        public Pair(int num, int id) {
            this.num = num;
            this.id = id;
        }
    }

    public static void main(String[] args){
        Scanner cin = new Scanner(new BufferedInputStream(System.in));
        int n = cin.nextInt();
        int[] arr = new int[n];
        for(int i = 0; i < n; i++)
            arr[i] = cin.nextInt();
        Arrays.sort(arr); //  升序排列
        Pair[] pairs = new Pair[n];
        for(int i = 0; i < n; i++) {
            int num = cin.nextInt();
            pairs[i] = new Pair(num, i);
        }
        Arrays.sort(pairs, (o1, o2) -> o2.num - o1.num); // 按照值降序排列
        int[] res = new int[n];
        for(int i = 0; i < n; i++)
            res[pairs[i].id] = arr[i];
        for(int i = 0; i < n; i++)
            System.out.print(res[i] + " ");
        System.out.println();
    }
}


Codeforces - 782C - Andryusha and Colored Balloons

題目連結

題目大意

就是給你一顆生成樹(n個頂點,n-1條邊),然後輸入n-1條邊,要你用1 ~ n之間儘可能少的顏色,來將n個頂點染色,有一個條件: 相鄰距離為2的點都是不同的顏色。

輸出總共需要多少種顏色,並且輸出每個頂點的顏色。
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

解析

寫了挺久(菜),還是沒有維護好count這個變數,最後還是看了下些解答。

count變數要在當前節點cur的所有孩子的迴圈遍歷中count++,因為遍歷一個之後,就找到了一種,所以遍歷一次就++,所以一開始dfscount = 0,至於最大值,只需要計算某個節點的最大值即可。

import java.io.BufferedInputStream;
import java.util.*;

public class Main {

    static ArrayList<Integer>G[];
    static int[] colors;
    static int res; // the number of colors

    static void dfs(int cur, int pre){
        int count = 0;
        for(int i = 0; i < G[cur].size(); i++){
            int to = G[cur].get(i);
            if(pre == to || colors[to] != -1) // 訪問過或者已經計算過
                continue;
            count++; //  it must
            while(count == colors[cur] || count == colors[pre])
                count++;
            colors[to] = count;
            dfs(to, cur);
        }
        res = Math.max(res, count);
    }

    public static void main(String[] args){
        Scanner cin = new Scanner(new BufferedInputStream(System.in));
        int n = cin.nextInt();
        G = new ArrayList[n+1];
        for(int i = 1; i <= n; i++)
            G[i] = new ArrayList<>();
        colors = new int[n+1];
        Arrays.fill(colors, -1);
        for(int i = 0; i < n-1; i++){
            int from = cin.nextInt();
            int to = cin.nextInt();
            G[from].add(to);
            G[to].add(from);
        }
        colors[1] = 1;
        res = 0;
        dfs(1, 0);
        System.out.println(res);
        for(int i = 1; i < n; i++)
            System.out.print(colors[i] + " ");
        System.out.println(colors[n]);
    }
}