zoukankan      html  css  js  c++  java
  • Comet OJ

    迫真小游戏
    已经提交 已经通过 时间限制:2000ms 内存限制:256MB

    73.98%
    提交人数:196

    通过人数:145

    题目描述

    H君喜欢在阳台晒太阳,闲暇之余他会玩一些塔防小游戏。

    H君玩的小游戏可以抽象成一棵 nn 个节点的有根树,树以 11 为根,每个点的深度定义为其到根的简单路径上的点数(根的深度为 11)。

    H君有 nn 个干员,H君会按照某种顺序把她们部署到树的每一个节点上,使得每个节点上恰好有一个干员。由于游戏的机制,他们对每个节点 ii 都给出了个限制参数 a_ia
    i

    ,要求H君在第 ii 个节点部署干员之前,所有深度 > a_i>a
    i

    的节点上不能有干员。同时游戏为了让玩家过关,保证了 a_ia
    i

    大于等于点 ii 的深度。

    H君将每一次部署干员的节点按顺序写在纸上,形成了一个 1 dots n1…n 的排列,H君为了获得更多的奖励,想要最小化这个排列的字典序。

    我们认为排列 c_1,c_2..c_nc
    1

    ,c
    2

    ..c
    n

    的字典序比排列 d_1,d_2..d_nd
    1

    ,d
    2

    ..d
    n

    的字典序小,当且仅当 c, dc,d 不完全相同且存在一个下标 ii,满足 c_i < d_ic
    i

    <d
    i

    且对于所有 1 le j < i1≤j<i 的 jj 都有 c_j = d_jc
    j

    =d
    j

    输入描述

    第一行一个数 nn 。

    接下来 n - 1n−1 行,每行两个数 x, yx,y 表示树上的一条边 。

    最后一行 nn 个数,表示 a_ia
    i

    数据范围:

    1le n le 5 imes 10^5, 1 le a_i le n1≤n≤5×10
    5
    ,1≤a
    i

    ≤n。

    输出描述

    第一行 nn 个数,表示字典序最小的排列。

    样例输入 1

    5
    1 5
    5 3
    1 4
    4 2
    1 3 3 3 2
    样例输出 1

    1 4 5 2 3
    样例输入 2

    10
    1 7
    7 8
    7 2
    8 9
    7 6
    2 4
    9 5
    8 10
    6 3
    5 3 4 4 5 3 5 3 5 4
    样例输出 2

    1 2 6 7 8 3 4 9 10 5

    题意:

    思路:
    首先dfs把整颗树跑一遍,得出每一个节点在第几层的信息,然后我们从1到n层扫一遍,对于每一层,我们把这一层上的所以节点操作,如果这个节点的a[i] 值是等于i的,那么这个节点在这一次操作中必须要部署,所以加入到一个大根堆中,否则加入到一个set中,同时用一个vector维护set中每一个a[i] 值加入了那些节点, 然后我们再从vector中查找是否有当前第i层的节点被介入到了set中,如果有就把它取出加入大根堆 ,然后把set的第一个元素(id最小的)与大根堆的堆顶(id最大的元素)比较,如果小于,就把它从set中取出,加入到堆中,一直这样操作,直到大于堆顶或者set为空,这样就可以使其字典序最小。

    细节见代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define rt return
    #define sz(a) int(a.size())
    #define all(a) a.begin(), a.end()
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
    using namespace std;
    typedef long long ll;
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
    inline void getInt(int* p);
    const int maxn=6e5;
    const int inf=0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    std::vector<int> son[maxn];
    int n;
    int a[maxn];
    int depth[maxn];
    void dfs(int x,int pre)
    {
    	depth[x]=depth[pre]+1;
    	for(auto y:son[x])
    	{
    		if(y!=pre)
    		{
    			dfs(y,x);
    		}
    	}
    }
    bool vis[maxn];
    std::vector<int> ans;
    struct node
    {
    	int ai;
    	int id;
    	node(){}
    	node(int ii,int aai)
    	{
    		id=ii;
    		ai=aai;
    	}
    	friend bool operator < (node x,node y)
        {
            //set套结构体要重载<运算符
            return x.id < y.id;
        }
    };
    struct cmp
    {
        bool operator ()(const node p1,const node p2)
        {
            return p1.id>p2.id;// 以first为比较对象的小根堆
        }
    };
    struct cmp2
    {
        bool operator ()(const node p1,const node p2)
        {
            return p1.id<p2.id;// 以first为比较对象的小根堆
        }
    };
    std::vector<node>  ceng[maxn];
    set<node> xgd;
    priority_queue<node,vector<node>,cmp2 > dgd;
    std::vector<int> jia[maxn];
    int main()
    {
        //freopen("D:\code\text\input.txt","r",stdin);
    	//freopen("D:\code\text\output.txt","w",stdout);
    	gbtb;
    	cin>>n;
    	int u,v;
    	repd(i,2,n)
    	{
    		cin>>u>>v;
    		son[v].pb(u);
    		son[u].pb(v);
    	}
    	repd(i,1,n)
    	{
    		cin>>a[i];
    		vis[a[i]]=1;
    	}
    	depth[0]=0;
    	dfs(1,0);
    	repd(i,1,n)
    	{
    		ceng[depth[i]].pb(node(i,a[i]));
    	}
    	repd(i,1,n)
    	{
    		for(auto x:ceng[i])
    		{
    			if(x.ai==i)
    			{
    				dgd.push(x);
    			}else
    			{
    				xgd.insert(x);
    				jia[x.ai].pb(x.id);
    			}
    		}
    		for(auto x:jia[i])
    		{
    			if(xgd.count(node(x,a[i]))==1)
    			{
    				xgd.erase(node(x,a[x]));
    				dgd.push(node(x,a[x]));
    			}
    		}
    		while((xgd.size()>0)&&(!dgd.empty())&&((*xgd.begin()).id<dgd.top().id))
    		{
    			dgd.push(*xgd.begin());
    			xgd.erase(xgd.begin());
    		}
    		std::vector<int> v;
    		v.clear();
    		while(!dgd.empty())
    		{
    			v.push_back(dgd.top().id);
    			dgd.pop();
    		}
    		reverse(ALL(v));
    		for(auto y:v)
    			ans.push_back(y);
    	}
    
    	while(!xgd.empty())
        {
            ans.pb((*xgd.begin()).id);
            xgd.erase(xgd.begin());
        }
        for(int i=0;i<ans.size();i++)
        {
            if(i!=0)
            {
                cout<<" "<<ans[i];
            }else{
                cout<<ans[i];
            }
        }
        cout<<endl;
    
    
        return 0;
    }
    
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    【零基础】极星量化入门九:找到boll的最优回测参数
    【零基础】极星量化入门八:简单的boll实盘
    【零基础】极星量化入门七:简单的boll回测
    解决element-ui中el-menu组件作为vue-router模式在刷新页面后default-active属性与当前路由页面不一致问题的方法
    vue+elementui selet框组件封装 传值
    b模块 小结
    移动端最简单的适配
    判断移动机型字符串
    前端记录cookie 点赞只能点一次
    用chrome预览微信浏览器访问需要OAuth2.0网页授权的页面 适合 微信朋友圈小游戏 HTML5小游戏 微信游戏网页
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/11031173.html
Copyright © 2011-2022 走看看