Educational Codeforces Round 54 (Rated for Div.2)


D. Edge Deletion

题意:一张n个点的无向图,保留其中k条边,使得有尽可能多的点与1的最短路长度不变。

做法:求出最短路树,然后自底向上删边即可。

#include <bits/stdc++.h>
#define pb push_back
#define P pair<ll,int>
typedef long long ll;
const ll inf = 1e18;
const int N = 3e5 + 7;
using namespace std;
int n, m , k;
struct edge{int e,nxt,id; ll w;
}E[N<<1],E2[N<<1];
int h[N], cc, h2[N],cc1;
void add(int u,int v,ll w,int d) {E[cc].e = v; E[cc].w = w; E[cc].id = d;E[cc].nxt = h[u]; h[u] = cc; ++cc;
}
void add2(int u,int v,ll w,int d) {E2[cc1].e = v; E2[cc1].w = w; E2[cc1].id = d;E2[cc1].nxt = h2[u]; h2[u] = cc1; ++cc1;
}
struct node{int x;ll d;node(){}node(int a,ll b){x=a;d=b;}bool operator < (const node a)const {return a.d < d;}
};
ll dis[N];
int vis[N], fa[N], fr[N];
void dij() {for(int i=1;i<=n;++i)dis[i]=inf;priority_queue<node> q;q.push(node(1,0));dis[1]=0; fa[1] = 0; fr[1] = -1;while(!q.empty()) {node tmp = q.top(); q.pop();int u=tmp.x;if(vis[u])continue;vis[u]=1;for(int i=h[u];~i;i=E[i].nxt) {int v=E[i].e;if(dis[v]>dis[u]+E[i].w) {dis[v]=dis[u]+E[i].w;fa[v] = u;fr[v] = E[i].id;q.push(node(v,dis[v]));}}}return;
}
struct node2{int u,v,id; ll w;node2(){}node2(int a,int b,ll c, int d) {u=a; v = b; w = c; id = d;}
};
node2 A[N];int dep[N];
void bfs() {queue<int> q;memset(dep,-1,sizeof(dep));q.push(1); dep[1] = 0;while(!q.empty()) {int u = q.front(); q.pop();for(int i = h2[u]; ~i ; i = E2[i].nxt) {int v = E2[i].e;if(dep[v] == -1) {dep[v] = dep[u] + 1;q.push(v);}}}
}vector< P > B;
int vis2[N];
int main() {scanf("%d%d%d",&n,&m,&k);memset(h,-1,sizeof(h));memset(h2,-1,sizeof(h2));for(int i = 1; i <= m; ++i) { int u,v; ll w;scanf("%d%d%lld",&u,&v,&w);A[i] = node2(u,v,w,i);add(u,v,w,i); add(v,u,w,i);}dij();for(int i = 2; i <= n; ++i) {int p = fr[i];vis2[p] = 1;add2(A[p].u,A[p].v,A[p].w,A[p].id);add2(A[p].v,A[p].u,A[p].w,A[p].id);}int e = n-1;bfs();for(int i = 2; i <= n; ++i) B.pb(P(dep[i],i));sort(B.begin(),B.end());for(int i = (int)B.size()-1; i >= 0; --i) {if(e > k) {vis2[fr[B[i].second]] = 0;--e;}}printf("%d\n",e);for(int i = 1; i <= m; ++i) if(vis2[i]) printf("%d ",i); puts("");
}

E. Vasya and a Tree

题意:给定一颗树,进行m个操作,每次将节点v子树中向下d+1层,的点全部加x,操作完成后询问每个点的值。

做法:dfs这棵树的同时,树状数组维护对应深度的影响,退出递归时,还原现场即可,类似于树上逆序对,因为操作的总和为m所以复杂度有保证。kd-tree和二维树状数组,都没卡过去。。。

#include <bits/stdc++.h>
#define pb push_back
#define fr first
#define sc second
#define P pair<int,ll>
typedef long long ll;
const int N = 300100;
using namespace std;
int n, m;
int dep[N],MX;
vector<int> G[N];
vector< P > A[N];
ll B[N], ans[N<<1];
void add(int x,ll v) {x += 10;for(int i=x;i;i-=(i&-i)) B[i] += v;
}
ll ask(int x) {ll ans = 0;x += 10;for(int i = x; i <= MX+20; i+=(i&(-i))) ans += B[i];return ans;
}
void dfs(int u,int fa) {dep[u] = dep[fa] + 1;MX = max(dep[u],MX);for(int i = 0; i < G[u].size(); ++i) {int v = G[u][i];if(v != fa) dfs(v,u);}
}
void dfs2(int u,int fa) {for(int i = 0; i < A[u].size(); ++i) add(A[u][i].fr,A[u][i].sc);ans[u] = ask(dep[u]);for(int i = 0; i < G[u].size(); ++i) {int v = G[u][i];if(v != fa) {dfs2(v,u);}}for(int i = 0; i < A[u].size(); ++i) add(A[u][i].fr,-A[u][i].sc);
}
int main() {scanf("%d",&n);for(int i = 1; i <= n-1; ++i) { int u,v;scanf("%d%d",&u,&v);G[u].pb(v); G[v].pb(u);}dep[0] = -1;dfs(1,0);scanf("%d",&m);for(int i = 1; i <= m; ++i) { int v,d; ll x;scanf("%d%d%lld",&v,&d,&x);A[v].pb(P(min(dep[v]+d,MX),x));}dfs2(1,0);for(int i = 1; i <= n; ++i)printf("%lld ",ans[i]);puts("");return 0;
}

F. Summer Practice Report

题意:有\(n\)页纸,第\(i\)页包含\(a[i]\)个\(T\), \(b[i]\)个\(F\),要求将所有的\(n\)页纸并起来后,不能有连续的\(k\)个\(T\)或\(F\),问是否有解。

做法:贪心构造dp。\(dp[i][0/1]\) 表示前\(i\)页纸放完,最后几个字符是\(T\)或\(F\)时,\(T\)或\(F\)最小的数目。如果\(min(dp[n][0], dp[n][1]) <= k\) 则满足条件。考虑如何\(dp\),设上一张末尾的\(T\)有\(pa\)张或\(F\)有\(pb\)张,当前这一张有\(a\)个\(T\),\(b\)个\(F\)。
先确定\(dp[i][0]\)的转移,考虑放满\(T\)然后向其中插入\(F\),用\(pa\)更新答案,那么如果\(pa<=k\)时,\(num\)即是需要插入的最少的\(F\)的个数,如果\(b == num\), 那么用最后剩下的\(T\)更新答案,同时可以知道\(b\)的上界就是每个\(T\)之间都插入\(k\)个\(F\),如果\(b>num\)且\(b <= k*a\),就可以在最后一个\(T\)之前插入一个\(F\),使得答案为\(1\)。用\(pb\)更新答案,思路类似,需要修改一下限制条件。\(dp[i][1]\) 也可以同样的转移。注意过程中会爆\(int\)

这道题在\(dp\)的同时贪心的转移,感觉思路十分清奇,看懂官方题解感觉自己dp烂的不要不要的。。。

#include <bits/stdc++.h>
typedef long long ll;
const int N = 300000+5;
const ll inf = 0x3f3f3f3f3f3f3f3f3f3f;
using namespace std;
int n, k, a[N], b[N];
int dp[N][2];
int cal(int pa, int pb, int a, int b) {ll ans = inf;if(pa <= k) {int num = (a + pa) / k + !!((a + pa) % k) - 1;if(b == num)ans = min(ans, pa + a - (ll)num*k);else if(b > num && (ll)b <= (ll)a*k)ans = min(ans, 1ll);}if(pb <= k) {int num = a / k + !!(a % k) - 1;if(b == num)ans = min(ans, a - (ll)num*k);else if(b > num && (ll)b <= (ll)(a-1)*k + (k-pb))ans = min(ans, 1ll);}return (int)ans;
}
int main() {scanf("%d %d", &n, &k);for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);for(int i = 1; i <= n; ++i) scanf("%d", &b[i]);for(int i = 1; i <= n; ++i) dp[i][0] = dp[i][1] = inf;for(int i = 1; i <= n; ++i) {dp[i][0] = cal(dp[i-1][0], dp[i-1][1], a[i], b[i]);dp[i][1] = cal(dp[i-1][1], dp[i-1][0], b[i], a[i]);}if(dp[n][0] <= k || dp[n][1] <= k) puts("YES");else puts("NO");return 0;
}

转载于:https://www.cnblogs.com/RRRR-wys/p/9969644.html

Educational Codeforces Round 54 (Rated for Div.2)相关推荐

  1. Educational Codeforces Round 54 (Rated for Div. 2) D Edge Deletion (SPFA + bfs)

    题目大意:给定你一个包含n个点m条边的无向图,现在最多在图中保留k条边,问怎么删除多的边,使得图中良好的节点数最多,求出保留在图中的边的数量和编号. 良好的节点定义为:删除某条边后该点到点1的最短距离 ...

  2. Educational Codeforces Round 54 (Rated for Div. 2): D. Edge Deletion(最短路树)

    题意: 给你n个点m条边的无向图,其中1号节点是市中心,你现在最多只能保留k条边,并要求所有点到市中心的最短路尽量不变(也就是说设点i到点1的最短路为di,那么删边之后,要保证尽可能多的点,它到1的最 ...

  3. Educational Codeforces Round 54 (Rated for Div. 2): E. Vasya and a Tree(DFS+差分)

    题意: 给你一棵n个节点的树,每个点有一个权值,初始全为0,m次操作,每次三个数(v, d, x)表示只考虑以v为根的子树,将所有与v点距离小于等于d的点权值全部加上x,求所有操作完毕后,所有节点的值 ...

  4. Educational Codeforces Round 90 (Rated for Div. 2)(A, B, C, D, E)

    Educational Codeforces Round 90 (Rated for Div. 2) Donut Shops 思路 分三种情况: a==c/ba == c / ba==c/b这个时候两 ...

  5. Educational Codeforces Round 114 (Rated for Div. 2) (A ~ F)全题解

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Educational Codeforces Round 114 (Rated for Div. 2) ...

  6. Educational Codeforces Round 106 (Rated for Div. 2)(A ~ E)题解(每日训练 Day.16 )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 Educational Codeforces Round 106 (Rated for Div. ...

  7. Educational Codeforces Round 37 (Rated for Div. 2) 1

    Educational Codeforces Round 37 (Rated for Div. 2) A.Water The Garden 题意:Max想给花园浇水.花园可被视为长度为n的花园床,花园 ...

  8. Educational Codeforces Round 89 (Rated for Div. 2)(A, B, C, D)

    Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords 思路 题意非常简单,就是得到最多的物品嘛,我们假定a, ...

  9. Educational Codeforces Round 114 (Rated for Div. 2) D. The Strongest Build 暴力 + bfs

    传送门 文章目录 题意: 思路: 题意: 你有nnn个装备槽,每个槽里面有cic_ici​个力量加成,对于每个槽只能选一个力量加成,现在给你mmm个力量组合[b1,b2,...,bn][b_1,b_2 ...

最新文章

  1. 二、进程的状态与转换
  2. 让我撸一次HashMap
  3. Python自然语言处理工具
  4. Exchange2003 OWA访问,IIS权限设置
  5. centos7安装sftp服务器
  6. requests爬取免费代理2
  7. 根据进程名判断该进程是否存在(C++)
  8. math、numpy、pandas NaN 判断
  9. win10 计算机 桌面图标不见了,win10系统桌面图标没了的解决方法
  10. 【5G NR】ZP CSI-RS资源配置
  11. java如何逆向工程_总结一下java如何进行逆向工程
  12. Windows磁盘格式、分区格式及类型
  13. 企业微信SDK接口API调用-通过手机号或微信好友添加客户
  14. 三菱或尝试抛弃后视镜,使用摄像头和AI技术来导航
  15. 华为端口聚合命令_华为交换机端口汇聚不同版本配置命令汇总
  16. matlab中zeros()函数
  17. 李刚疯狂JAVA面向对象章节
  18. 城乡投票源码php_PHP微信公众号投票活动系统源码 独立版
  19. HDU 6112 今夕何夕【2017百度之星】【日期模拟计算】【基姆拉尔森计算公式】【蔡勒公式】
  20. 何隆昌 帆软报表汇总,相减,注意事项

热门文章

  1. leetcode54:螺旋矩阵
  2. 7-1 活动选择问题 (25 分)(思路+详解+扩展)宝 今天你AC了吗!!!
  3. 7-43 字符串关键字的散列映射 (25 分)(思路+详解+不懂的兄弟们来呀)兄弟们我干了5个小时,一个一个测试点过的
  4. Java实现队列(循环队列,链队列)
  5. [JavaWeb-Bootstrap]Bootstrap响应式布局
  6. [JS-DOM]DOM概述
  7. 高等数学下-赵立军-北京大学出版社-题解-练习10.2
  8. C++map容器-大小和互换
  9. 给定一个n节点二叉树,写出一个O(n)时间的非递归的过程,将该树每个结点的关键字输出(算法导论第三版第十章10.4-5)
  10. Sumsets POJ - 2229(计数dp)