Hdu 5325 2015多校对抗赛三

2024-08-31 12:48
文章标签 2015 hdu 多校 对抗赛 5325

本文主要是介绍Hdu 5325 2015多校对抗赛三,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5325

Crazy Bobo

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 1305    Accepted Submission(s): 399


Problem Description
Bobo has a tree,whose vertices are conveniently labeled by 1,2,...,n.Each node has a weight  wi . All the weights are distrinct.
A set with m nodes  v1,v2,...,vm  is a Bobo Set if:
- The subgraph of his tree induced by this set is connected.
- After we sort these nodes in set by their weights in ascending order,we get  u1,u2,...,um ,(that is, wui<wui+1  for i from 1 to m-1).For any node  x  in the path from  ui  to  ui+1 (excluding  ui  and  ui+1 ),should satisfy  wx<wui .
Your task is to find the maximum size of Bobo Set in a given tree.

Input
The input consists of several tests. For each tests:
The first line contains a integer n ( 1n500000 ). Then following a line contains n integers  w1,w2,...,wn  ( 1wi109 ,all the  wi  is distrinct).Each of the following n-1 lines contain 2 integers  ai  and  bi ,denoting an edge between vertices  ai  and  bi  ( 1ai,bin ).
The sum of n is not bigger than 800000.

Output
For each test output one line contains a integer,denoting the maximum size of Bobo Set.

Sample Input
  
7 3 30 350 100 200 300 400 1 2 2 3 3 4 4 5 5 6 6 7

Sample Output
  
5

Author
ZSTU

Source
2015 Multi-University Training Contest 3
题目意思:一颗树上有n个节点,由n-1条边连接,每个节点有个权值。
定义一个集合:这个集合内的点按权值小到大排序,要求相连两点路径上的所有点(不包括这两端点)的权值比起始点权值小。
求最大集合的大小。
分析:
对于相连三点:     小  中  大  (小到中,中到大,此序列满足要求)
小  大  中 (小到中,路径上有个节点大,不满足要求)
中  小  大  (小到中,满足,中到大,中间有小的节点,但是仍然小于起始节点中,满足)
有以上三种情况,小中大表示点的权值。可见,如果我们把树弄出有向边,那么一定是相对小权值指向相对大权值。
那么,就可以从权最小的节点往外搜,直到外围都是大点。按照上述方式建边,权最小的点的入度一定为0。
最后取个最大值就是答案。
当树是一条链的时候,dfs递归深度很大,需手动扩栈。并且需要记忆化搜索才不会T,所谓记忆化搜索就是标记保存搜索的点的结果,下次碰到此点就不往下搜了。
貌似bfs会T,虽然不会有栈问题,bfs没有记忆搜索。

还有另外一种相对的方法,从最大值节点出发,回到最小值节点,最后取最大值也是答案。但是,建边的话就应该大边指向小边了。
就是从大值节点往小值节点宽搜,一步一步把节点数加到小值节点上面。

#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
int w[500001];
int rudu[500001];
int mark[500001];
vector <int> edge[500001];
void dfs(int u,int &cnt){int len=edge[u].size();for(int i=0;i<len;i++){int v=edge[u][i];if(mark[v]!=0)cnt+=mark[v];//记忆化搜索else{int tmp=cnt;dfs(v,++cnt);mark[v]=cnt-tmp;}}
}
void bfs(int u,int &cnt){//没有记忆化搜索queue <int> que;que.push(u);while(!que.empty()){int u=que.front();que.pop();int len=edge[u].size();for(int i=0;i<len;i++){int v=edge[u][i];que.push(v);cnt+=1;}}
}
int main(){int n;while(~scanf("%d",&n)){for(int i=1;i<=n;i++){edge[i].clear();rudu[i]=0;mark[i]=0;scanf("%d",&w[i]);}for(int i=1;i<n;i++){int a,b;scanf("%d%d",&a,&b);if(w[a]>w[b]){edge[b].push_back(a);rudu[a]++;}else {edge[a].push_back(b);rudu[b]++;}}int ans=0;for(int i=1;i<=n;i++){int tmp=1;if(rudu[i]==0){dfs(i,tmp);mark[i]=tmp;
//                bfs(i,tmp);//TLEans=max(ans,tmp);}}printf("%d\n",ans);}return 0;
}

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
int w[500001];
int rudu[500001];
int cnt[500001];
vector <int> edge[500001];
int main(){int n;while(~scanf("%d",&n)){for(int i=1;i<=n;i++){edge[i].clear();rudu[i]=0;cnt[i]=0;scanf("%d",&w[i]);}queue <int> que;for(int i=1;i<n;i++){int a,b;scanf("%d%d",&a,&b);if(w[a]<w[b])swap(a,b);edge[a].push_back(b);rudu[b]++;}for(int i=1;i<=n;i++)if(rudu[i]==0)que.push(i);while(!que.empty()){int u=que.front();que.pop();int len=edge[u].size();for(int i=0;i<len;i++){int v=edge[u][i];cnt[v]+=cnt[u]+1;rudu[v]--;if(rudu[v]==0)que.push(v);}}int tot=0;for(int i=1;i<=n;i++){tot=max(tot,cnt[i]);}printf("%d\n",tot+1);}return 0;
}





这篇关于Hdu 5325 2015多校对抗赛三的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1123949

相关文章

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hdu 2093 考试排名(sscanf)

模拟题。 直接从教程里拉解析。 因为表格里的数据格式不统一。有时候有"()",有时候又没有。而它也不会给我们提示。 这种情况下,就只能它它们统一看作字符串来处理了。现在就请出我们的主角sscanf()! sscanf 语法: #include int sscanf( const char *buffer, const char *format, ... ); 函数sscanf()和

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

hdu 3790 (单源最短路dijkstra)

题意: 每条边都有长度d 和花费p,给你起点s 终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。 解析: 考察对dijkstra的理解。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstrin

hdu 2489 (dfs枚举 + prim)

题意: 对于一棵顶点和边都有权值的树,使用下面的等式来计算Ratio 给定一个n 个顶点的完全图及它所有顶点和边的权值,找到一个该图含有m 个顶点的子图,并且让这个子图的Ratio 值在所有m 个顶点的树中最小。 解析: 因为数据量不大,先用dfs枚举搭配出m个子节点,算出点和,然后套个prim算出边和,每次比较大小即可。 dfs没有写好,A的老泪纵横。 错在把index在d

hdu 1102 uva 10397(最小生成树prim)

hdu 1102: 题意: 给一个邻接矩阵,给一些村庄间已经修的路,问最小生成树。 解析: 把已经修的路的权值改为0,套个prim()。 注意prim 最外层循坏为n-1。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstri

hdu 1285(拓扑排序)

题意: 给各个队间的胜负关系,让排名次,名词相同按从小到大排。 解析: 拓扑排序是应用于有向无回路图(Direct Acyclic Graph,简称DAG)上的一种排序方式,对一个有向无回路图进行拓扑排序后,所有的顶点形成一个序列,对所有边(u,v),满足u 在v 的前面。该序列说明了顶点表示的事件或状态发生的整体顺序。比较经典的是在工程活动上,某些工程完成后,另一些工程才能继续,此时