题目链接:http://codeforces.com/problemset/problem/796/C

题目大意:有n家银行,第一次可以攻击任意一家银行(能量低于自身),跟被攻击银行相邻或者间接相邻(距离<=2)的银行能量+1,除了第一次外,攻击一家银行需要满足以下条件:

      ①:跟被攻击过后的银行相邻;

      ②:能量低于攻击者

      ③:银行没有被攻击过

题解:可以从题意得知,比如攻击银行i,如果说银行i能量为t,跟银行距离>=2的银行中能量最大的为mx,自身至少所需能量=max(t+1,mx+2),因为其他银行能量最多也只能+2;

   这样,我们只需要遍历1~n家银行找到最少需要的能量就可以了;

   这里我们用了两个c++数据结构,vector和multiset。vector属于<vector>是动态数组,multiset属于<set>会自动将里面的数字按从小到大排好;

   

 #include<iostream>
#include<cstdio>
#include<set>
#include<vector>
using namespace std;
const int N=3e5+;
vector<int>v[N];
multiset<int>ms; int main(){
int n,a,b;
int arr[N];
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",arr+i);
ms.insert(arr[i]);
}
for(int i=;i<=n-;i++){
scanf("%d %d",&a,&b);
v[a].push_back(b);
v[b].push_back(a);
}
int ans=<<;
multiset<int>::iterator it;
for(int i=;i<=n;i++){//遍历n家银行,找到需要最少能量的银行
//存下银行i的值后,在ms中删除
int temp=arr[i];
ms.erase(ms.find(arr[i]));
//找到跟i相邻的银行,比较后,在ms中删除
for(int j=;j<v[i].size();j++){
int k=v[i][j];
temp=max(temp,arr[k]+);
ms.erase(ms.find(arr[k]));
}
//比较距离大于2的银行能量最大值+2和temp的大小,保证每个银行都可以攻击
if(!ms.empty()){
it=ms.end();
temp=max(temp,*(--it)+);//由于ms.end()指向最后一位,而不是最后一个元素所以--it;
}
//还原ms中删除的元素
ms.insert(arr[i]);
for(int j=;j<v[i].size();j++){
int k=v[i][j];
ms.insert(arr[k]);
}
ans=min(temp,ans);//找到所有情况中最少的能量
}
printf("%d\n",ans);
}

另外附上一种贪心写法:

C1为mx个数  C2为mx-1个数 
ans=mx 只有当C1=1&&正好有C2个mx-1与mx相连  
ans=mx+1 只有当存在一个点满足 其距离<=1内 mx的个数为C1 
其余情况ans=mx+2

 #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> ii;
const ll inf=1e10;
const int N=2e6+;
ll n,a[N],vis[N],can[N];
vector<int> e[N];
void solve()
{
ll C1=,C2=,mx=-inf,u;
for(int i=;i<=n;i++)
mx=max(a[i],mx);
for(int i=;i<=n;i++)
{
if(a[i]==mx)
C1++,u=i;
else if(a[i]==mx-)
C2++;
}
ll ans=inf;
if(C1==)//
{
int cnt=;
for(int i=;i<e[u].size();i++)
{
int v=e[u][i];
if(a[v]==mx-)
cnt++;
}
if(cnt==C2)
ans=mx;
}
if(ans==inf)
{
for(int i=;i<=n&&ans==inf;i++)//遍历边O(n),找到相邻为1内,有C1个mx
{
ll res=;
if(a[i]==mx)
res++;
for(int j=;j<e[i].size();j++)
{
int v=e[i][j];
if(a[v]==mx)
res++;
}
if(res==C1)
ans=mx+;
}
}
if(ans==inf)
ans=mx+;
cout<<ans<<endl;
}
int main()
{
while(cin>>n)
{
for(int i=;i<=n;i++)
scanf("%I64d",&a[i]),e[i].clear();
int u,v;
for(int i=;i<=n-;i++)
{
scanf("%d%d",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
solve();
}
return ;
}

最新文章

  1. Step deep into GLSL
  2. Cardinality Feedback
  3. Android解惑 - 为什么要用Fragment.setArguments(Bundle bundle)来传递参数(转)
  4. MR中的combiner和partitioner
  5. 《Genesis-3D开源游戏引擎完整实例教程-2D射击游戏篇07:全屏炸弹》
  6. Android开发之R文件丢失
  7. UIDynamic(一)
  8. 服务列表 - Sina App Engine
  9. uoj#73 【WC2015】未来程序
  10. JS 执行上下文
  11. css换行
  12. codecs and formats of digital media
  13. Luogu2046 NOI2010 海拔 平面图、最小割、最短路
  14. Mind Manager X 10 registry backup key under windows XP
  15. WIN10平板 如何修改网络IP地址为固定
  16. 初次搭建spring-boot 整合ssm(有许多小坑)
  17. day44
  18. Android学习笔记十:异步处理
  19. Chapter 7 Integrity(完整性), Views(视图), Security(安全性), and Catalogs(目录)
  20. 一名优秀的UI设计师应该具备哪些条件?

热门文章

  1. BUG1 解决java compiler level does not match the version of the installed java project facet
  2. Lnmp上安装Yaf学习(一)
  3. centos install python3 pip3
  4. Dockerfile编写注意事项
  5. NO.6LINUX基本命令
  6. go build 不同系统下的可执行文件
  7. git爬坑不完全指北(二):failed to push some refs to ‘XXX’的解决方案
  8. js 正则表达式 整数或小数
  9. Mysql服务优化
  10. 基于Vue + Vuex + Vue-router + Webpack 2.0打造微信界面