CF #228 div1 B. Fox and Minimal path

题目链接:http://codeforces.com/problemset/problem/388/B

大意是用不超过1000个点构造一张边权为1的无向图,使得点1到点2的最短路的个数为给定值k,其中k为不超过1e9的正整数,输出邻接矩阵

构造方法也不止一种

有一种分层构造方法是这样的,

第i层的点与1号点距离为i-1

第一层放置1号点

第二层放置3号和4号点,分别与上一层的1号点相连,他们的最短路为1,且个数也为1

接下来每一层都会比上一层的点数要多1,第i+1层,首先与第i层的前i个点相连,然后第i+1个点与第i层的所有点相连

 

这样构造的话,最短路个数按照层表示会是

1

1 1

1 1 2

1 1 2 4

1 1 2 4 8

1 1 2 4 8 16

这样下去。主要就是利用了1+2+...+2^n=2^(n+1)-1 再多一个个数为1的点就能凑成下一个2的幂了

 

其他的构造方法还可以是不断地分出2个岔路,再汇合,再分岔,这样的话每个汇合点也是一个2的幂,但是要注意每个汇合点不能直接连到2号点,因为每个汇合点与1号点距离是不相等的,处理方法可以是往下拖到一条“总线”上,总线末端与2号点相连

 

下面是第一种构造方式的代码

 1 import java.io.OutputStream;
 2 import java.io.IOException;
 3 import java.io.InputStream;
 4 import java.io.PrintWriter;
 5 import java.util.StringTokenizer;
 6 import java.io.IOException;
 7 import java.io.BufferedReader;
 8 import java.io.InputStreamReader;
 9 import java.io.InputStream;
10 
11 public class Main {
12     public static void main(String[] args) {
13         InputStream inputStream = System.in;
14         OutputStream outputStream = System.out;
15         InputReader in = new InputReader(inputStream);
16         PrintWriter out = new PrintWriter(outputStream);
17         Task solver = new Task();
18         solver.solve(1, in, out);
19         out.close();
20     }
21 
22     static class Task {
23         void addEdge(boolean[][] g, int u, int v) {
24             g[u][v] = true;
25             g[v][u] = true;
26         }
27 
28         public void solve(int testNumber, InputReader in, PrintWriter out) {
29             int k = in.nextInt();
30             boolean[][] g = new boolean[1001][10001];
31             int n = 2;
32             int from = 0, to = 1;
33             for (int p = 1, l = 1; p <= k; p <<= 1, l++) {
34                 int nfrom = n;
35                 for (int i = from; i < to; i++) {
36                     addEdge(g, i, n++);
37                 }
38                 for (int i = from; i < to; i++) {
39                     addEdge(g, i, n);
40                 }
41                 from = nfrom;
42                 to = ++n;
43             }
44             for (int i = from + 1; i < to; i++) {
45                 if ((k & (1 << i - from - 1)) != 0) {
46                     addEdge(g, i, 1);
47                 }
48             }
49             out.println(n);
50             for (int i = 0; i < n; i++) {
51                 for (int j = 0; j < n; j++) {
52                     out.print((g[i][j] ? "Y" : "N"));
53                 }
54                 out.println();
55             }
56         }
57 
58     }
59 
60     static class InputReader {
61         private final BufferedReader reader;
62         private StringTokenizer tokenizer;
63 
64         public InputReader(InputStream stream) {
65             reader = new BufferedReader(new InputStreamReader(stream));
66             tokenizer = null;
67         }
68 
69         public String next() {
70             while (tokenizer == null || !tokenizer.hasMoreTokens()) {
71                 try {
72                     tokenizer = new StringTokenizer(reader.readLine());
73                 } catch (IOException e) {
74                     throw new RuntimeException(e);
75                 }
76             }
77             return tokenizer.nextToken();
78         }
79 
80         public int nextInt() {
81             return Integer.parseInt(next());
82         }
83 
84     }
85 }
View Code

 

posted @ 2016-07-02 15:02  活在夢裡  阅读(257)  评论(0编辑  收藏  举报