芽衣:染上你的颜色

染色初步...

给图上的顶点指定颜色,使图上任何临接的顶点都被染成不同的颜色

我们想要知道的是最少使用几种颜色以及具体方案

《组合数学》上面有个贪心的染色法...

设G是图,它的顶点按某一顺序记为x1,x2, ..., xn。

(1)对顶点x1指定颜色1

(2)对每个i=2,3,...,n,令p是不与xi邻接的顶点的颜色重复的, (序号)最小的颜色,对xi指定颜色p

 

Problem H. Path or Coloring

Input file: Output file: Time limit: Memory limit:

pathorcoloring.in pathorcoloring.out 1 second
256 mebibytes

Do you like NP-hard problems? For example, let us consider the following two:

Coloring problem. You are given an undirected graph G and an integer k. For each vertex of the graph, choose color φ(v) so that all colors are integers between 1 and k, and any two vertices connected by an edge have different color.

Simple k-path problem. You are given an undirected graph G and an integer k. Find a simple path of length k. Formally, you need to choose such sequence of k + 1 unique vertices v1, v2, . . . , vk+1 that any two consecutive verices are connected by an edge.

You are given an undirected graph G and an integer k. Solve any one of these two problems for them. The choice is yours.

Input

The first line of input contains an integer T , the number of test cases (1 ≤ T ≤ 1000). The description of each test case consists of several lines.

The first line of each description of containts two integers n and m: the number of vertices and the number of edges in the graph (1 ≤ n ≤ 1000, 1 ≤ m ≤ 10 000). On the next line, the integer k is given (1 ≤ k ≤ n). Each of the next m lines contains two integers a and b: the numbers of two verices connected by an edge (1 ≤ a, b ≤ n).

It is guaranteed that the given graphs have no self-loops and no multiple edges. Additionally, the total number of edges in all given graphs does not exceed 100 000.

Output

For each test case, print one of the following:

• The word “path” followed by k + 1 numbers of vertices: a simple path of length k.
• The word “coloring” followed by n integers from 1 to k: a coloring of the graph into k colors. • The word “neither” if there is no simple path of length k and no coloring into k colors.

If there exist both a valid path and a valid coloring, you can print either a path or a coloring. If there are several valid paths or several valid colorings, you can print any one path or any one coloring, respectively.

尼玛啊我不喜欢NPhard问题!

给出一个简单图,和一个数字k,要求任意选一个问题做答:

1.输出图的一个k染色方案

2.输出图的一个长度为k的简单路径

如果两种都无解输出neither

 

不知道怎么做k长简单路径,就g了。实际上:

如果有k染色方案,输出即可

如果没有k染色方案,一定存在k长简单路径,neither不存在的

因为染色数小于等于最长路径:

考虑完全图Kn,染色数为n,最长路径n。

任意删去一些边(保持连通),染色数会减小或不变

 

如果在贪心染色时,在给随意一个点指定颜色1后,从这个点邻接的点进行接下来的染色(dfs序)

那这个路径就是:颜色1,2, ..., k, k+1对应的顶点

#include
const int maxn = 1e3+7, maxm = 2e4+7;
int v[maxm], col[maxn], vis[maxn], head[maxn], nxt[maxm];
int n, m, k, tot, pos;
void addedge(int x, int y){
    v[++tot] = y;
    nxt[tot] = head[x];
    head[x] = tot;
}
void dfs(int u){
    pos++;
    for(int i = head[u]; i; i = nxt[i]){
        if(col[v[i]]){
            //printf("pos : %d ", pos);
            //printf("near %d is %d\n", u, v[i]);
            vis[col[v[i]]] = pos;
        }
    }
    for(int i = 1; ; i++){
        if(vis[i] < pos){
            col[u] = i;
            //printf("pos : %d ", pos);
            //printf("give %d color %d\n", u, i);
            break;
        }
    }
    for(int i = head[u]; i; i = nxt[i]){
        //printf("%d %d %d col v i %d\n", pos, i, v[i], col[v[i]]);
        if(!col[v[i]])
            dfs(v[i]);
    }
}
void solve(){
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= n; i++)
        col[i] = head[i] = vis[i] = 0;
    pos = tot = 0;
    while(m--){
        int x, y;
        scanf("%d%d", &x, &y);
        addedge(x, y);
        addedge(y, x);
    }
    for(int i = 1; i <= n; i++){
        if(!col[i])
            dfs(i);
    }
    int x = 0;
    bool flag = 1;
    for(int i = 1; i <= n; i++){
        if(col[i] > k){
            x = i;
            flag = 0;
            break;
        }
    }
    /*for(int i = 1; i <= n; i++)
        printf(" %d", col[i]);
    puts("color");*/
    if(flag){
        printf("coloring");
        for(int i = 1; i <= n; i++)
            printf(" %d", col[i]);
        return;
    }
    printf("path");
    int loop = k;
    printf(" %d", x);
    while(loop){
        for(int i = head[x]; i; i = nxt[i]){
            if(col[v[i]] == loop){
                x = v[i];
                break;
            }
        }
        printf(" %d", x);
        loop--;
    }
}
int main(){
    int t;
    scanf("%d", &t);
    while(t--){
        solve();
        puts("");
    }
    return 0;
}
/*
 1
 5 10 4
 1 2 2 3 3 4 4 5 5 1 1 3 1 4 2 5 4 2 3 5
*/
View Code

 

转载于:https://www.cnblogs.com/DearDongchen/p/7635784.html

你可能感兴趣的:(芽衣:染上你的颜色)