zoukankan      html  css  js  c++  java
  • Luogu P5603 小C与桌游

    题目链接https://www.luogu.org/problem/P5603?contestId=22461

    题目描述

    这个桌游的地图可以被抽象成一个 n 个点,m 条边的有向无环图不保证连通),小C在这个地图上行走,小C能走到某个点当且仅当能够到达这个点的所有点都已经被小C走到。小C会走到每个点恰好 11 次,并且他能走到哪些点与他当前所在的点没有关系(即可以走到与当前所在的点没有连边的点,只要满足之前的条件)。

    [小C每走到一个标号比之前走到的点都大的点,他就会有 frac{1}{2} ​ 的概率从对手那里拿到 1 块筹码,有 frac{1}{2} ​ 的概率给对手 1 块筹码 ]

    双方初始各有 19198101919810 个筹码。

    小C的运气时好时坏,所以他希望你帮他计算出:

    • 在最优情况下,即他每次都能从对手那里拿到筹码时,他采取最优的行走方式能得到的筹码数。
    • 在最劣情况下,即对手每次都能从他那里拿到筹码时,他采取最优的行走方式会失去的筹码数。

    框中是废话

    在月赛中是IOI赛制,于是蒟蒻我一打完就交了上去,“咣”拿了4分。一看,原来是指针打错了,改好之后又是“咣”的一声拿了46分。之后蒟蒻我苦思冥想(狂膜大佬hsm)终于A了。
    

    在题目中我们可以看出在最优情况下,我们维护一个小根堆,从题目可以看出我们每次去出最小的节点进行dfs,就可以使得到的硬币最多。

    在题目中我们可以看出在最坏情况下,一开始因为最优情况,我因为只要维护一个大根堆就可以了于是,“咣”的一下只有46分。仔细研究题目可以发现我们要取出当前可以达到所有小于当前已到达的最大节点的点。

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    const int N = 5e5 + 10;
    const int Max = 1919810;
    
    int n, m, ans, tot, num;
    int head[N], kk[N];
    
    priority_queue <int>q;
    
    struct nod{
    	int ru1, id, ru2;
    }a[N];
    
    struct Edg{
    	int to, nxt;
    }e[N];
    
    template <typename T>
    inline void read(T &x){
    	x = 0;
    	char c = getchar();
    	T op = 1;
    	for(; c < '0' || c > '9'; c = getchar())
    		if(c == '-')	op = -1;
    	for(; c <= '9' && c >= '0'; c = getchar())
    		x = (x << 3) + (x << 1) + c - '0';
    	x *= op;
    }
    
    inline void add(int x, int y){
    	e[++tot].to = y;
    	e[tot].nxt = head[x];
    	head[x] = tot;
    }
    
    inline void dfs1(){
    	num = -1;
    	for(int i = 1; i <= n; ++i)
    		if(!a[i].ru1)	q.push(-i);
    	while(!q.empty()){
    		int x = q.top();
    		q.pop();
    		x *= -1;
    		if(x > num)	num = x, ++ans;
    		for(int i = head[x]; i; i = e[i].nxt){
    			a[e[i].to].ru1--;
    			if(!a[e[i].to].ru1)	q.push(-e[i].to);
    		}
    	}
    	printf("%d
    ", ans > Max ? Max : ans);
    	ans = 0;
    }
    
    inline void dfs2(){
    	num = -1;
    	for(int i = 1; i <= n; ++i)
    		if(!a[i].ru2)	q.push(i);
    	while(!q.empty()){
    		int x = q.top();
    		q.pop();
    		tot = 0;
    		if(x > num)	num = x, ++ans;
    		for(int i = head[x]; i; i = e[i].nxt){
    			a[e[i].to].ru2--;
    			if(!a[e[i].to].ru2)	q.push(e[i].to);
    		}
    		while(!q.empty()){
    			int s = q.top();
    			q.pop();
    			if(s > num)	{kk[++tot] = s; continue;}
    			for(int i = head[s]; i; i = e[i].nxt){
    				a[e[i].to].ru2--;
    				if(!a[e[i].to].ru2)	q.push(e[i].to);
    			}
    		}
    		for(int i = 1; i <= tot; ++i)
    			q.push(kk[i]);
    	}
    	printf("%d
    ", ans > Max ? Max : ans);
    }
    
    int main(){
    	read(n), read(m);
    	for(int i = 1; i <= m; ++i){
    		int x, y;
    		read(x), read(y);
    		add(x, y);
    		a[y].ru1++, a[y].ru2++;
    	}
    	dfs1();
    	dfs2();
    	return 0;
    }
    
  • 相关阅读:
    怎样在过滤器中读取配置信息?
    怎样将直接数据库中Json字段,映射到Mybatis中的Map类型?
    spring/boot 打包,资源/配置/业务文件分离
    使用VS Code推送代码到GitHub
    Clion下jni配置
    curl post请求总是返回417错误
    ubuntu 12.10 apt-get 源
    如何让git小乌龟工具TortoiseGit记住你的账号密码
    FastCgi与Cgi
    Libevent核心原理
  • 原文地址:https://www.cnblogs.com/ZmeetL/p/11801701.html
Copyright © 2011-2022 走看看