zoukankan      html  css  js  c++  java
  • hdoj_4547

    CD操作

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
    Total Submission(s): 551    Accepted Submission(s): 161


    Problem Description
      在Windows下我们可以通过cmd运行DOS的部分功能,其中CD是一条很有意思的命令,通过CD操作,我们可以改变当前目录。
      这里我们简化一下问题,假设只有一个根目录,CD操作也只有两种方式:
      
      1. CD 当前目录名\...\目标目录名 (中间可以包含若干目录,保证目标目录通过绝对路径可达)
      2. CD .. (返回当前目录的上级目录)
      
      现在给出当前目录和一个目标目录,请问最少需要几次CD操作才能将当前目录变成目标目录?
     

    Input
    输入数据第一行包含一个整数T(T<=20),表示样例个数;
    每个样例首先一行是两个整数N和M(1<=N,M<=100000),表示有N个目录和M个询问;
    接下来N-1行每行两个目录名A B(目录名是只含有数字或字母,长度小于40的字符串),表示A的父目录是B。
    最后M行每行两个目录名A B,表示询问将当前目录从A变成B最少要多少次CD操作。
    数据保证合法,一定存在一个根目录,每个目录都能从根目录访问到。
     

    Output
    请输出每次询问的结果,每个查询的输出占一行。
     

    Sample Input
    2 3 1 B A C A B C 3 2 B A C B A C C A
     

    Sample Output
    2 1 2

    记录父节点以及每隔节点到根节点的距离,模板题!

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <map>
    using namespace std;
    #pragma warning(disable : 4996)
    const int MAXN = 100005;
    typedef struct Edge
    {
    	int v;
    	int w;
    	int next;
    	int lca;
    }Edge;
    
    typedef struct Query
    {
    	int u;
    	int v;
    	int lca;
    }Query;
    Query q[MAXN];
    int cnt, edge_head[MAXN], ask_head[MAXN];
    int father[MAXN], dist[MAXN];
    bool visited[MAXN];
    Edge edge[2 * MAXN], ask[2 * MAXN];
    int in[MAXN];
    map<string, int>Map;
    int num;
    
    int Getnum(string str)
    {
    	if(Map.find(str) == Map.end())
    	{
    		Map[str] = num++;
    	}
    	return Map[str];
    }
    
    int find(int x)
    {
    	if (x != father[x])
    	{
    		father[x] = find(father[x]);
    	}
    	return father[x];
    }
    
    void add_edge(int x, int y, int z)
    {
    	edge[cnt].v = y;
    	edge[cnt].w = z;
    	edge[cnt].next = edge_head[x];
    	edge_head[x] = cnt++;
    
    }
    
    void add_ask(int x, int y, int cast)
    {
    	ask[cnt].v = y;
    	ask[cnt].w = cast;
    	ask[cnt].next = ask_head[x];
    	ask_head[x] = cnt++;
    }
    
    void Tarjan(int k)
    {
    	visited[k] = true;
    
    	for (int i = ask_head[k]; i != 0; i = ask[i].next)
    	{
    		if (visited[ask[i].v])
    		{
    			ask[i].lca = find(ask[i].v);
    			q[ask[i].w].lca = ask[i].lca;
    		}
    	}
    
    	for (int i = edge_head[k]; i != 0; i = edge[i].next)
    	{
    		if (!visited[edge[i].v])
    		{
    			dist[edge[i].v] = dist[k] + edge[i].w;
    			Tarjan(edge[i].v);
    			edge[i].v = find(edge[i].v);
    			father[edge[i].v] = k;
    		}
    	}
    }
    
    int main()
    {
    	freopen("in.txt", "r", stdin);
    	int i, m, n;
    	int x, y;
    	int t;
    	int ans, root;
    	string s1, s2;
    	scanf("%d", &t);
    	while (t--)
    	{
    		scanf("%d %d", &n, &m);
    		for (i = 1; i <= n; i++)
    		{
    			edge_head[i] = ask_head[i] = 0;
    			father[i] = i;
    			visited[i] = false;
    			in[i] = 0;
    		}
    
    		Map.clear();
    		cnt = num = 1;
    		for (i = 1; i < n; i++)
    		{
    			cin >> s1 >> s2;
    			x = Getnum(s1);
    			y = Getnum(s2);
    			//cout << x << " " << y << endl;
    			add_edge(x, y, 1);
    			add_edge(y, x, 1);
    			in[x]++;
    		}
    		cnt = 1;
    		for (i = 1; i <= m; i++)
    		{
    			cin >> s1 >> s2;
    			x = Getnum(s1);
    			y = Getnum(s2);
    			add_ask(x, y, i);
    			add_ask(y, x, i);
    			q[i].u = x;
    			q[i].v = y;
    		}
    		root = 0;
    		for(int i = 1; i <= n; i++)
    		{
    			if(in[i] == 0)
    			{
    				root = i;
    				break;
    			}
    		}
    		//cout << root << endl;
    		dist[root] = 0;
    		Tarjan(root);
    		for (int i = 1; i <= m; i++)
    		{
    			ans = dist[q[i].u] - dist[q[i].lca];
    			if(q[i].lca != q[i].v)
    			{
    				ans++;
    			}
    			if(q[i].u == q[i].v)
    			{
    				ans = 0;
    			}
    			printf("%d\n", ans);
    		}
    	}
    	return 0;
    }



  • 相关阅读:
    Linux下安装maven
    非连续性及反脆弱
    高手是怎么练成的
    思维型大脑
    编写文档五轮模式
    Nginx初识
    ida快捷键
    ida+gdb调试任意平台
    gcc常用命令使用
    ida调试ios应用
  • 原文地址:https://www.cnblogs.com/lgh1992314/p/5834972.html
Copyright © 2011-2022 走看看