zoukankan      html  css  js  c++  java
  • 编程之美——彩色的树

    描述

    给定一棵n个节点的树,节点编号为1, 2, …, n。树中有n - 1条边,任意两个节点间恰好有一条路径。这是一棵彩色的树,每个节点恰好可以染一种颜色。初始时,所有节点的颜色都为0。现在需要实现两种操作:

    1. 改变节点x的颜色为y;

    2. 询问整棵树被划分成了多少棵颜色相同的子树。即每棵子树内的节点颜色都相同,而相邻子树的颜色不同。

    输入

    第一行一个整数T,表示数据组数,以下是T组数据。

    每组数据第一行是n,表示树的节点个数。接下来n - 1行每行两个数i和j,表示节点i和j间有一条边。接下来是一个数q,表示操作数。之后q行,每行表示以下两种操作之一:

    1. 若为"1",则询问划分的子树个数。

    2. 若为"2 x y",则将节点x的颜色改为y。

    输出

    每组数据的第一行为"Case #X:",X为测试数据编号,从1开始。

    接下来的每一行,对于每一个询问,输出一个整数,为划分成的子树个数。

    数据范围

    1 ≤ T ≤ 20

    0 ≤ y ≤ 100000

    小数据

    1 ≤ n, q ≤ 5000

    大数据

    1 ≤ n, q ≤ 100000

    样例输入

    2
    3
    1 2
    2 3
    3
    1
    2 2 1
    1
    5
    1 2
    2 3
    2 4
    2 5
    4
    1
    2 2 1
    2 3 2
    1
    

    样例输出

    Case #1:
    1
    3
    Case #2:
    1
    5


    分析: 可以用图的深度遍历或者树的深度遍历来解决。

    图的遍历
    #include<iostream>
    #include<vector>
    using namespace std;
    
    
    #define MAXVEX  100000             //最大顶点数,应由用户定义
    
    
    typedef struct EdgeNode         //边表结点
    {
    	int adjvex;         //邻接点域,存储该顶点对应的下标	
    	struct EdgeNode *next;      //链域,指向下一个邻接点
    }EdgeNode;
    
    typedef struct VertexNode       //顶点表结构
    {
    	int color;        //顶点域,存储顶点信息
    	EdgeNode *firstedge;        //边表头指针
    }VertexNode, AdjList[MAXVEX];
    
    typedef struct
    {
    	AdjList adjList;
    	int numVertexes, numEdges;  //图中当前顶点数和边数
    }GraphList;
    
    
    //建立图的邻接表结构
    void CreateGraph(GraphList *g)
    {
    	int i, j, k;
    	EdgeNode *e;
    	EdgeNode *f;
    	cin>>g->numVertexes;
    	g->numEdges = g->numVertexes-1;
    
    	for(i = 1; i <= g->numVertexes; i++)
    	{
    
    		g->adjList[i].color = 0;          //输入顶点信息
    		g->adjList[i].firstedge = NULL;          //将边表置为空表
    		
    	}
    	//建立边表
    	for(k = 0; k < g->numEdges; k++)
    	{
    		
    		int p,q;
    		cin>>p>>q;
    		//向内存申请空间,生成边表结点
    		e = (EdgeNode *)malloc(sizeof(EdgeNode));
    		
    		//邻接序号为j
    		e->adjvex = q;
    		//将e指针指向当前顶点指向的结构
    		e->next = g->adjList[p].firstedge;
    		//将当前顶点的指针指向e
    		g->adjList[p].firstedge = e;
    
    		f = (EdgeNode *)malloc(sizeof(EdgeNode));
    		
    		f->adjvex = p;
    		f->next = g->adjList[q].firstedge;
    		g->adjList[q].firstedge = f;
    	}
    }
    
    bool visited[MAXVEX];
    
    //邻接表的深度递归算法
    void DFS(GraphList& g, int i)
    {
    	EdgeNode *p;
    	visited[i] = true;
    	p = g.adjList[i].firstedge;
    	while(p)
    	{
    		if(!visited[p->adjvex] && (g.adjList[i].color == g.adjList[p->adjvex].color))
    		{
    			DFS(g, p->adjvex);           //对访问的邻接顶点递归调用
    		}
    		p = p->next;
    	}
    }
    
    //邻接表的深度遍历操作
    int DFSTraverse(GraphList& g)
    {
    	int cnt=0;
    	int i;
    	for(i = 1; i <= g.numVertexes; i++)
    	{
    		visited[i] = false;
    	}
    	for(i = 1; i <= g.numVertexes; i++)
    	{
    		if(!visited[i])
    		{
    			DFS(g, i);
    			cnt++;
    		}
    	}
    
    	return cnt;
    }
    
    
    
    int main()
    {
    	int T;
    	int n;
    	int q;
    	int x,y;
    	int chs;
    
    	vector<vector<int> > vvec;
    	vector<int> vec;
    	GraphList g;
    	cin>>T;
    
    	while(T--)
    	{
    		vec.clear();
    		CreateGraph(&g);
    		cin>>q;
    		for(int i=0; i<q; i++)
    		{
    			cin>>chs;
    			if(chs==1)
    			{
    				vec.push_back(DFSTraverse(g));
    			}
    			if(chs==2)
    			{
    				cin>>x>>y;
    				g.adjList[x].color = y;
    			}
    		}
    
    		vvec.push_back(vec);
    
    	}
    
    
    	for(int i=0; i<vvec.size(); i++)
    	{
    		cout<<"Case #"<<i+1<<":"<<endl;
    		for(int j =0; j<vvec[i].size(); j++)
    			cout<<vvec[i][j]<<endl;
    
    	}
    
    	return 0;
    }
    

      

    树的遍历

    #include<iostream>
    #include <vector>
    const int maxVex = 100000;
    using namespace std;
    
    int parent[maxVex];
    int child[maxVex];
    int color[maxVex];
    bool visited[maxVex];
    int num; //tree node number
    
    void create()
    {
    	int x,y;
    	cin>>num;
    	for (int i=1; i<=num; i++)
    	{
    		parent[i]=0;
    		child[i]=0;
    		color[i]=0;
    	}
    	for(int i=0; i<num-1; i++)
    	{
    		cin>>x>>y;
    		child[x]=y;
    		parent[y]=x;
    	}
    }
    
    void DFS(int i)
    {
    	visited[i] = true;
    	for (int j = child[i]; j<=num&&j>=1&&color[i]==color[j]; j = child[j])
    	{
    		if(!visited[j])
    			DFS(j);
    	}
    
    	for (int j = parent[i]; j<=num&&j>=1&&color[i]==color[j]; j = parent[j])
    	{
    		if(!visited[j])
    			DFS(j);
    	}
    }
    
    int DFSTraverse()
    {
    	int cnt=0;
    	for(int i=1; i<=num; i++)
    	{
    		visited[i]=false;
    	}
    
    	for(int i=1; i<=num; i++)
    	{
    		if(!visited[i])
    		{                                                                                                                                                                                                           
    			DFS(i);
    			cnt++;
    		}
    	}
    	return cnt;
    }
    
    
    int main()
    {
    	int T;
    	int n;
    	int q;
    	int x,y;
    	int chs;
    
    	vector<vector<int> > vvec;
    	vector<int> vec;
    	
    	cin>>T;
    
    	while(T--)
    	{
    		vec.clear();
    		create();
    
    		cin>>q;
    		for(int i=0; i<q; i++)
    		{
    			cin>>chs;
    			if (chs==1)
    			{
    				vec.push_back(DFSTraverse());
    			}
    			if(chs==2)
    			{
    				cin>>x>>y;
    				color[x]=y;
    			}
    		}
    
    		vvec.push_back(vec);
    	}
    
    
    	for(int i=0; i<vvec.size(); i++)
    	{
    		cout<<"Case #"<<i+1<<":"<<endl;
    		for(int j =0; j<vvec[i].size(); j++)
    			cout<<vvec[i][j]<<endl;
    
    	}
    
    	return 0;
    }
    
    
    /*
    
    
    2
    3
    1 2
    2 3
    3
    1
    2 2 1
    1
    5
    1 2
    2 3
    2 4
    2 5
    4
    1
    2 2 1
    2 3 2
    1
    
    */
    

      


    http://blog.csdn.net/linxinyuluo/article/details/6847851

  • 相关阅读:
    不会全排列算法(Javascript实现),我教你呀!
    驰骋页面,谁主沉浮-也谈清除浮动
    你不知道的parseInt
    Javascript函数重载,存在呢—还是存在呢?
    在这个看脸的世界,该如何优雅的创建JS对象
    Python 函数的使用小结
    Python 集合(set)的使用总结
    Python 文件操作
    python 中字典的操作(增、删、改、查)
    python 中list的操作(循环、切片、增、删、改、查、反转、排序)
  • 原文地址:https://www.cnblogs.com/aituming/p/4456339.html
Copyright © 2011-2022 走看看