Google Code jam——Radio Receiver

   题目:http://code.google.com/codejam/contest/dashboard?c=842485#s=p2

   题目大意是,能否从用户选定的一个点A出发,遍历所有的路径,每条路径只能遍历一次,最后返回点A,如果不能,问需要添加的最少的路径数?每两个点之间可以添加任意条路径。

   是《离散数学》图论的知识,第一,首先必须是连通图,因为要遍历所有的路径。其次,因为从点A出发,又要重新返回点A,所以所有的点的度数必须为偶数。

   因此我的做法是,先找出所有的联通子图,统计连通子图能否形成欧拉回路,即奇数度数点的个数,连接n个连通子图至少需要n条边,而这那条边能够帮助一个连通子图增加一个度数,因此,连接一个连通子图至少需要两条边,可以增加两度,也就是减少一条边。因此最后的连通子图与边的关系可以确定为,sum(edge[i]-1) + cl. if cl >= 2, edge[i] > 0. edge[i]表示第i个连通子图的变成欧拉回路图需要边的数目(也即是奇数度节点的个数/2),cl表示,连通子图的个数

   代码如下:

#include<iostream> #include <fstream> #include <string> #include<algorithm> #define SIZE 1001 using namespace std; ifstream fin("B-large-practice.in"); ofstream fout("B-large-practice.out"); int cas; int index = 1; int n; int r; int color[SIZE] = {0}; int cl; int sum; int map[SIZE][SIZE] = {0}; int edge[SIZE] = {0}; int path[SIZE] = {0}; int pl; void read() { memset(map, 0, sizeof(int) * SIZE * SIZE); memset(edge, 0, sizeof(int) * SIZE); memset(color, 0, sizeof(int) * SIZE); fin >> n >> r; int x, y; for (int i=0; i < r; i ++) { fin >> x >> y; map[x][y] ++; map[y][x] ++; }//end for i } void breadnode(int c) { for (int i=0; i < pl; i ++) { int node = path[i]; for (int j = 0; j < n; j ++) { if (color[j] == 0 && map[node][j] > 0) { color[j] = c; path[pl] = j; pl ++; } }//end for j }//end for i } void colornode() { cl = 1; for (int i=0; i < n; i ++) { if (color[i] == 0) { for (int j=0; j <n; j ++) { if (map[i][j] > 0&&color[j] == 0) { color[i] = cl; path[0] = i; pl = 1; breadnode(cl); cl ++; }//end if }//end for j }//end if color[i] }//end for } void caledge() { sum = 0; for (int i=0; i < n; i ++) { if (color[i] != 0) { int radios = 0; for (int j = 0; j < n; j ++) { radios += map[i][j]; } if (radios&1) { edge[color[i]] ++; } }//end if }//end for i for (int i=1; i < cl; i ++) { edge[i] = edge[i] >> 1; if (edge[i] > 0 && cl > 2) { edge[i] --; } sum += edge[i]; } } int main() { fin >> cas; while (index <= cas) { read(); colornode(); caledge(); if (cl > 2) { fout << "Case #" << index << ": " << cl + sum - 1<< endl; } else { fout << "Case #" << index << ": " << sum << endl; } index ++; } return 0; }

  

  

  

你可能感兴趣的:(Google Code jam——Radio Receiver)