PAT-A-1154 Vertex Coloring (25分) C/C++实现(图论)

A proper vertex coloring is a labeling of the graph’s vertices with colors such that no two vertices sharing the same edge have the same color. A coloring using at most k colors is called a (proper) k-coloring.
Now you are supposed to tell if a given coloring is a proper k-coloring.

Input Specification:
Each input file contains one test case. For each case, the first line gives two positive integers N and M (both no more than 10^​4), being the total numbers of vertices and edges, respectively. Then M lines follow, each describes an edge by giving the indices (from 0 to N−1) of the two ends of the edge.
After the graph, a positive integer K (≤ 100) is given, which is the number of colorings you are supposed to check. Then K lines follow, each contains N colors which are represented by non-negative integers in the range of int. The i-th color is the color of the i-th vertex.

Output Specification:
For each coloring, print in a line k-coloring if it is a proper k-coloring for some positive k, or No if not.

Sample Input:
10 11
8 7
6 8
4 5
8 4
8 1
1 2
1 4
9 8
9 1
1 0
2 4
4
0 1 0 1 4 1 0 1 3 0
0 1 0 1 4 1 0 1 0 0
8 1 0 1 4 1 0 5 3 0
1 2 3 4 5 6 7 8 8 9

Sample Output:
4-coloring
No
6-coloring
No

  • 题目大意:
    给出一个由n个节点和m条边构成的图,图中的每个节点有自己的颜色,对于图中任意一条边,如果边上的两个节点的颜色不同,并且图中一共有k种颜色的节点,那么就输出k-coloring,否则输出No;

  • 思路:

    1. 用一个结构体储存每条边的两个节点,用一个数组储存每个节点的颜色;
    2. 遍历所有的边,判断边上的两个节点的颜色是否相同;
#include <iostream>
#include <vector>
#include <set>
using namespace std;
struct Line
{
    int vertice1, vertice2;
};
vector <Line> line;
int main()
{
    int n, m, k;
    cin >> n >> m;
    for (int i = 0; i < m; i++)
    {
        Line temp;
        cin >> temp.vertice1 >> temp.vertice2;
        line.push_back(temp);
    }
    cin >> k;
    while (k-- > 0)
    {
        set <int> dic;
        int color[10000];
        bool flag = true;
        for (int i = 0; i < n; i++)
        {
            cin >> color[i];
            dic.insert(color[i]);
        }
        for (int i = 0; i < m; i++)
        {
            if (color[line[i].vertice1] == color[line[i].vertice2])
            {
                flag = false;
                break;
            }
        }
        
        if (flag)
        {
            cout << dic.size() << "-coloring\n";
        }
        else
        {
            cout << "No\n";
        }  
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是C语言实现的informed-rrt*算法的代码,注释已详细说明每个步骤的含义和作用: ```c #include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #define MAX_VERTICES 10000 #define MAX_EDGES 20000 #define MAX_PATH 1000 #define PI 3.14159265358979323846 // 定义Tree结构体表示树 typedef struct { int parent; double position[2]; } Tree; // 定义Edge结构体表示边 typedef struct { int start; int end; double cost; } Edge; // 定义Path结构体表示路径 typedef struct { int vertices[MAX_PATH]; int count; } Path; // 定义全局变量 int num_vertices = 0; int num_edges = 0; Tree tree[MAX_VERTICES]; Edge edges[MAX_EDGES]; Path path; // 定义函数 double distance(double x1, double y1, double x2, double y2) { return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2)); } int random_vertex() { // 生成随机点 return rand() % num_vertices; } int nearest_vertex(double x, double y) { // 找到距离当前点(x, y)最近的树节点 int nearest = 0; double min_dist = distance(x, y, tree[0].position[0], tree[0].position[1]); for (int i = 1; i < num_vertices; i++) { double dist = distance(x, y, tree[i].position[0], tree[i].position[1]); if (dist < min_dist) { nearest = i; min_dist = dist; } } return nearest; } int new_vertex(double x, double y) { // 向树中添加新节点 int v = num_vertices; tree[v].parent = -1; tree[v].position[0] = x; tree[v].position[1] = y; num_vertices++; return v; } int can_reach(double x1, double y1, double x2, double y2, double radius) { // 判断两点之间是否可以直接连接 double dist = distance(x1, y1, x2, y2); if (dist > radius) { return 0; } for (int i = 0; i < num_edges; i++) { double x3 = tree[edges[i].start].position[0]; double y3 = tree[edges[i].start].position[1]; double x4 = tree[edges[i].end].position[0]; double y4 = tree[edges[i].end].position[1]; if (distance(x1, y1, x3, y3) < radius && distance(x2, y2, x4, y4) < radius) { double a = y2 - y1; double b = x1 - x2; double c = x2 * y1 - x1 * y2; double d1 = fabs(a * x3 + b * y3 + c) / sqrt(pow(a, 2) + pow(b, 2)); double d2 = fabs(a * x4 + b * y4 + c) / sqrt(pow(a, 2) + pow(b, 2)); if (d1 < radius && d2 < radius) { return 0; } } } return 1; } void add_edge(int start, int end) { // 向树中添加新边 edges[num_edges].start = start; edges[num_edges].end = end; edges[num_edges].cost = distance(tree[start].position[0], tree[start].position[1], tree[end].position[0], tree[end].position[1]); num_edges++; tree[end].parent = start; } void find_path(int start, int end) { // 寻找从起点到终点的路径 path.count = 0; int current = end; while (current != start) { path.vertices[path.count] = current; path.count++; current = tree[current].parent; } path.vertices[path.count] = start; path.count++; } void informed_rrt_star(double start_x, double start_y, double goal_x, double goal_y, double radius, double goal_bias, double max_iter, double step_size, double goal_tolerance) { // informed-rrt*算法实现 srand(time(NULL)); num_vertices = 0; num_edges = 0; int start_vertex = new_vertex(start_x, start_y); while (num_vertices < max_iter) { double p = (double)rand() / RAND_MAX; int x, y; if (p < goal_bias) { x = goal_x; y = goal_y; } else { x = (int)(rand() % 1000); y = (int)(rand() % 1000); } int nearest = nearest_vertex(x, y); double theta = atan2(y - tree[nearest].position[1], x - tree[nearest].position[0]); double new_x = tree[nearest].position[0] + step_size * cos(theta); double new_y = tree[nearest].position[1] + step_size * sin(theta); if (can_reach(tree[nearest].position[0], tree[nearest].position[1], new_x, new_y, radius)) { int new_vertex_index = new_vertex(new_x, new_y); add_edge(nearest, new_vertex_index); for (int i = 0; i < num_vertices; i++) { double dist = distance(tree[new_vertex_index].position[0], tree[new_vertex_index].position[1], tree[i].position[0], tree[i].position[1]); if (tree[i].parent == -1 && dist < radius && can_reach(tree[new_vertex_index].position[0], tree[new_vertex_index].position[1], tree[i].position[0], tree[i].position[1], radius)) { add_edge(i, new_vertex_index); } } if (distance(new_x, new_y, goal_x, goal_y) < goal_tolerance) { int goal_vertex = new_vertex(goal_x, goal_y); add_edge(new_vertex_index, goal_vertex); if (can_reach(tree[new_vertex_index].position[0], tree[new_vertex_index].position[1], goal_x, goal_y, radius)) { add_edge(goal_vertex, new_vertex_index); find_path(start_vertex, goal_vertex); break; } } } } } int main() { informed_rrt_star(0, 0, 1000, 1000, 50, 0.1, 10000, 50, 10); for (int i = path.count - 1; i >= 0; i--) { printf("%d %d\n", (int)tree[path.vertices[i]].position[0], (int)tree[path.vertices[i]].position[1]); } return 0; } ``` 上述代码实现了informed-rrt*算法,具体实现步骤如下: 1. 定义树(Tree)、边(Edge)和路径(Path)的结构体,以及全局变量num_vertices、num_edges、tree、edges和path,用于存储算法中的数据结构和结果。 2. 实现计算两点之间距离的函数distance。 3. 实现随机生成树节点编号的函数random_vertex。 4. 实现找到距离当前点最近的树节点编号的函数nearest_vertex。 5. 实现向树中添加新节点的函数new_vertex。 6. 实现判断两点之间是否可以直接连接的函数can_reach。 7. 实现向树中添加新边的函数add_edge。 8. 实现寻找从起点到终点的路径的函数find_path。 9. 实现informed-rrt*算法的主体函数informed_rrt_star,其中包含以下步骤: 1. 初始化全局变量num_vertices和num_edges为0,并生成起点。 2. 循环执行以下步骤,直到达到最大迭代次数: 1. 生成一个随机点,其中p是随机数,如果p小于目标偏差(goal_bias),则生成终点位置。 2. 找到距离随机点最近的树节点。 3. 计算从最近节点到随机点的角度,并计算出新节点的位置。 4. 判断最近节点和新节点之间是否可以直接连接,如果可以,则添加新节点和新边。 5. 对所有未连接的节点,如果距离新节点小于半径(radius),且可以直接连接,则添加新边。 6. 如果新节点距离终点小于目标容差(goal_tolerance),则添加新节点和新边,并寻找从起点到终点的路径。 10. 在main函数中调用informed_rrt_star函数,并输出从起点到终点的路径。 上述代码实现了informed-rrt*算法的基本框架,但实际使用中可能需要根据具体场景进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值