银河

SKYIV STUDIO

  博客园 :: 首页 :: 博问 :: 闪存 :: :: :: 订阅 订阅 :: 管理 ::
Timus 1080. Map Colouring 讨论地图的着色问题。

1080. Map Colouring

Time Limit: 1.0 second
Memory Limit: 16 MB
We consider a geographical map with N countries numbered from 1 to N (0 < N < 99). For every country we know the numbers of other countries which are connected with its border. From every country we can reach to any other one, eventually crossing some borders. Write a program which determines whether it is possible to colour the map only in two colours — red and blue in such a way that if two countries are connected their colours are different. The colour of the first country is red. Your program must output one possible colouring for the other countries, or show, that such colouring is impossible.

Input

On the first line is written the number N. On the following N lines, the i-th line contains the countries to which the i-th country is connected. Every integer on this line is bigger than i, except the last one which is 0 and marks that no more countries are listed for country i. If a line contains 0, that means that the i-th country is not connected to any other country, which number is larger than i.

Output

The output contains exactly one line. If the colouring is possible, this lines must contain a list of zeros and ones, without any separators between them. The i-th digit in this sequence is the colour of the i-th country. 0 corresponds to red colour, and one — to blue colour. If a colouring is not possible, output the integer −1.

Sample

inputoutput
3
2 0
3 0
0
010
Problem Author: Emil Kelevedzhiev
Problem Source: Winter Mathematical Festival Varna '2001 Informatics Tournament

这道题目给出地图上的 N 个国家,这个地图只有一块大陆,没有孤岛。要求写一个程序使用红色和蓝色这两种颜色给地图上的所有国家着色,且相邻的国家使用不同的颜色。

给定的输入的第一行是地图上的国家的数目 N。后面跟着 N 行,每一行表示第 i 个国家的邻国的编号列表,该列表仅列出编号比 i 大的国家,以 0 结束。

要求程序依次输出各个国家的着色,0 代表红色,1 代表蓝色,且第一个国家着红色。如果没有合适的着色方案,就输出 -1。

 1 using System;
 2 using System.IO;
 3 using System.Collections.Generic;
 4 
 5 namespace Skyiv.Ben.Timus
 6 {
 7   // http://acm.timus.ru/problem.aspx?space=1&num=1080
 8   sealed class T1080
 9   {
10     static void Main()
11     {
12       Dictionary<int,object>[] map = Read(Console.In);
13       bool?[] color = new bool?[map.Length];
14       color[0= false;
15       if (!Search(map, color, 0)) Console.Write(-1);
16       else foreach (bool c in color) Console.Write(c ? 1 : 0);
17     }
18     
19     static Dictionary<int,object>[] Read(TextReader reader)
20     {
21       Dictionary<int,object>[] map = new Dictionary<int,object>[int.Parse(reader.ReadLine())];
22       for (int i = 0; i < map.Length; i++) map[i] = new Dictionary<int,object>();
23       for (int i = 0; i < map.Length; i++)
24       {
25         string[] ss = reader.ReadLine().Split();
26         for (int k = 0; k < ss.Length - 1; k++)
27         {
28           int j = int.Parse(ss[k]) - 1;
29           map[i][j] = map[j][i] = null;
30         }
31       }
32       return map;
33     }
34     
35     static bool Search(Dictionary<int,object>[] map, bool?[] color, int k)
36     {
37       foreach (int v in map[k].Keys)
38         if (color[v] == null)
39         {
40           color[v] = !color[k];
41           if (!Search(map, color, v)) return false;
42         }
43         else if (color[v] == color[k]) return false;
44       return true;
45     }
46   }
47 }

在上述程序中,第 10 到 17 行是 Main 方法,首先调用 Read 方法读取输入到 map 数组中(第 12 行),然后分配颜色数组 color (第 13 行),该数组的数据类型是可空布尔值,null 值表示该国家尚未着色,false 表示红色,true 表示蓝色。接着将第一个国家着红色(第 14 行)。第 15 行调用 Search 方法寻找着色方案,如果没有找到合适的着色方案就输出 -1,否则就依次输出各个国家的着色(第 16 行)。

第 19 到 33 行的 Read 方法读取输入。第 21 行读取国家的数目并分配表示地图的 map 数组,该数组的数据类型是 Dictionary<int,object>,其索引键表示所有邻国的编号。第 23 行开始的循环依次读取输入。注意第 29 行设置所有的邻国,而不是只有编号更大的邻国。

第 35 到 45 行的 Search 方法使用深度优先搜索算法来寻找着色方案,其中参数 k 表示国家编号。第 37 行开始的循环遍历第 k 个国家的所有邻国。第 38 行判断如果该邻国尚未着色,就着另一种颜色(第 40 行),并使用该邻国的编号 v 行为参数递归调用自身继续搜索(第 41 行)。第 43 行判断如果该邻国已经着相同颜色,就返回搜索失败。否则继续搜索,直到遍历所有邻国。

著名的 四色定理 是说只需四种颜色就一定可以给上述的地图着色,这也是第一个主要由计算机证明的定理。上述程序如果作一些修改,应该可以用于验证(不是证明)四色定理。


返回目录
posted on 2008-12-18 18:13  银河  阅读(1979)  评论(0编辑  收藏  举报