D. Treelabeling 二分图染色

本文探讨了D. Treelabeling问题,主要聚焦于如何进行二分图的染色算法。通过深入分析,揭示了c++实现该算法的关键步骤和思路,为解决此类问题提供了实践指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接

/*I think*/
#include <iostream>
#include <cstring>
#include <string>
#include<map>
#include<queue>
#include<set>
#include<algorithm>
#include<cmath>
#include<vector>
#define debug(a) cout<<#a<<"="<<a<<endl;
#define cd(a) scanf("%lld", &a)
#define ll long long
#define PII pair<int, int>
#define _for(i, a, b) for (int i = a; i < b; i++)
#define For(i, a, b) for (int i = a; i <= b; i++)
#define foR(i, b, a) for (int i = b; i >= a; i--)
#define ms(a,b) memset(a, b, sizeof a)
#define gcd(a, b) __gcd(a, b)
#define lcm(a, b) a / gcd(a, b) * b
#define INF 0x3f3f3f3f
using namespace std;
const int N = 2e5+10,mod=1000000007;
double eps=1e-7;

vector<int> e[N], id[2];
int ans[N];
void dfs(int u,int fa,int val){
    id[val].push_back(u);
    for(auto v:e[u]){
        if(v!=fa){
            dfs(v, u, val ^ 1);
        }
    }
}


void sov()
{
    int n;
    cin >> n;

    For(i, 1, n) e[i].clear();
    id[0].clear();
    id[1].clear();
    For(i,1,n-1){
        int u, v;
        cin>>u>>v;
        e[u].push_back(v);
        e[v].push_back(u);
    }

    vector<int> va[30];
    for (int i = 1; i <=n;i++){
        for (int j = 20; j >= 0;j--){
            if(i&(1<<j)){
                va[j].push_back(i);
                break;
            }
        }
    }

    dfs(1, 1, 1);

    if(id[0].size()>id[1].size())
        swap(id[0], id[1]);

    int len = id[0].size(), p = 0;
    for (int i = 0; i <= 20;i++){
        if (va[i].size() == (1 << i) && len&(1<<i)  ){
            // 去凑出来len个(小的肯定可以凑出来 )
            for(auto t:va[i]){
                ans[id[0][p++]] = t;
            }
            va[i].clear();
        }
    }
    //把剩下的i放进去
    p = 0;
    for (int i = 0; i <= 20;i++){
        for(auto t:va[i]){
            ans[id[1][p++]] = t;
        }
    }
    For(i,1,n)printf("%d ",ans[i]);
    printf("\n");
}        

signed main(){
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif

    int OvO;
    cin >> OvO;
    while(OvO--){
        sov();
    }

    return 0;
}
### 判断二分图C++实现 在C++中,可以通过染色法来判断一个图是否为二分图。这种方法的核心思想是对图中的顶点进行两色染色,并确保相邻节点的颜色不同。如果能够成功完成这一过程,则说明该图为二分图。 以下是基于深度优先搜索(DFS)方法的一个具体实现: ```cpp #include <iostream> #include <vector> using namespace std; enum Color { Unknown, Red, Black }; // 定义图的邻接表形式 class Graph { public: vector<vector<int>> adjList; explicit Graph(int n) : adjList(n) {} void addEdge(int u, int v) { adjList[u].push_back(v); adjList[v].push_back(u); // 如果是无向图 } const vector<int>& Adj(int vertex) const { return adjList[vertex]; } }; bool isBipartite(const Graph& graph, int verticesCount) { vector<Color> colors(verticesCount, Unknown); for (int i = 0; i < verticesCount; ++i) { if (colors[i] == Unknown && !ColorDFS(graph, colors, i, Red)) { return false; } } return true; } bool ColorDFS(const Graph& graph, vector<Color>& colors, int currentVertex, Color color) { colors[currentVertex] = color; for (auto neighbor : graph.Adj(currentVertex)) { if (colors[neighbor] == color) { return false; } if (colors[neighbor] == Unknown) { if (!ColorDFS(graph, colors, neighbor, color == Red ? Black : Red)) { return false; } } } return true; } int main() { int V = 6; // 假设图中有6个顶点 Graph g(V); g.addEdge(0, 1); g.addEdge(0, 3); g.addEdge(1, 2); g.addEdge(3, 4); g.addEdge(4, 5); if (isBipartite(g, V)) { cout << "The given graph is a bipartite graph." << endl; } else { cout << "The given graph is not a bipartite graph." << endl; } return 0; } ``` 上述代码通过枚举每一个未访问过的节点并尝试对其进行染色操作,利用递归的方式遍历整个连通子图。一旦发现冲突情况即返回`false`[^2]。 #### 关键点解释 - **Graph类定义**:采用邻接表的形式存储图数据结构。 - **ColorDFS函数逻辑**:此部分实现了具体的深搜策略,在每次进入新的节点时为其分配一种颜色并与父节点保持异色关系。 - **isBipartite接口封装**:提供了一个高层抽象供外部调用者测试任意给定图实例是否满足二分性质条件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值