Codeforces 796C 想法
来源:互联网 发布:python pack_into 编辑:程序博客网 时间:2024/05/21 04:42
两家银行称为间接邻居 他们的距离是2且中点银行没有被hack
每次hack完一家银行后 他的邻居和间接邻居的防御值都+1
开始你可以任意选一家银行hack 接下来你只能hack已经hack过的银行的邻居
求最小攻击值能hack掉所有银行
题解:
这道题是细节题
令mix1为最大的防御值 mix2为次大的防御值
答案很明显 只有三种可能 mix1 mix1+1 mix1+2
当只有一家银行时 答案就是mix1 return 0
当只有两家银行时 答案就是max( mix1 ,mix2+1 ) return 0
当所有的点防御值都一样时 当银行呈烟花状时(一个银行是其他所有银行的邻居) 那么我们先hack这家银行 答案就是 mix1+1 return 0
否则 答案就是mix1+2 return 0
当最大的防御值的数大于等于3个时 如果呈烟花状(一个烟花包含所有最大的防御值的银行) 答案就是mix1+1
否则 答案就是mix1+2
当最大的防御值的数等于2个时 如果这两个点距离小于等于2 那么答案就是mix1+1
否则 答案就是mix1+2
当最大的防御值的数等于1时 如果以这个点为中心和所有次大的防御值的银行呈烟花状 答案就是 mix1
否则 答案就是 max( mix1 , mix2+2 )
还有一种暴力做法(我听了想打人)
把这些点都放进multiset里面 然后for每个点 对于每个点 他相邻的点都+1 然后把这个点和相邻的都删掉 再从multiset中找出最大的+2 再把删去的点放回去
这样的做法复杂度是nlongn 因为每个点被放进去的次数是这个点的du+1
这里放分类讨论的代码
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<deque>using namespace std;struct node{int to,nex;}edge[600005];int head[300005],cnt,num[300005],du[300005];void add(int u,int v){edge[cnt].to=v;edge[cnt].nex=head[u];head[u]=cnt++;}deque<int>sp;int vis[300005];int main(){int n,i,j,x,y,mix1=-1000000001,mix2=-1000000001;scanf("%d",&n);for(i=1;i<=n;i++){scanf("%d",&num[i]);if(num[i]>=mix1){mix2=mix1;mix1=num[i];}else if(num[i]>=mix2)mix2=num[i];}int num1=0,num2=0;for(i=1;i<=n;i++){if(mix1==num[i])num1++;else if(mix2==num[i])num2++;}int td=0,lab=0,mis=0;;memset(head,-1,sizeof(head));for(i=1;i<n;i++){scanf("%d%d",&x,&y);add(x,y);add(y,x);if(num[x]==mix1){ du[y]++; if(du[y]>mis){ mis=du[y]; lab=y; }}if(num[y]==mix1){ du[x]++; if(du[x]>mis){ mis=du[x]; lab=x; }}td=max(td,du[x]);td=max(td,du[y]);}if(num1==n){if(n==1)printf("%d\n",mix1);else if(td==n-1)printf("%d\n",mix1+1);else printf("%d\n",mix1+2);return 0;}if(n==1){printf("%d\n",mix1);return 0;}else if(n==2){if(num[1]==num[2])printf("%d\n",num[1]+1);else printf("%d\n",mix1);return 0;}if(num1>=3){ if(mis==num1||(mis==num1-1&&num[lab]==mix1))printf("%d\n",mix1+1);else printf("%d\n",mix1+2);}else if(num1==2){for(i=1;i<=n;i++){if(num[i]==mix1)break;}int flag=1;vis[i]=1;sp.push_back(i);while(!sp.empty()){ int f=sp.front(); sp.pop_front(); if(vis[f]>=4)continue; if(num[f]==mix1&&f!=i){ flag=0; break; } for(j=head[f];~j;j=edge[j].nex){ int v=edge[j].to; if(vis[v])continue; vis[v]=vis[f]+1; sp.push_back(v); }}if(flag){printf("%d\n",mix1+2);}else printf("%d\n",mix1+1);}else{int nums=0;for(i=1;i<=n;i++){if(num[i]==mix1)break;}for(j=head[i];~j;j=edge[j].nex){if(num[edge[j].to]==mix2)nums++;}if(nums==num2)printf("%d\n",mix1);else printf("%d\n",max(mix1,mix2+2));}return 0;}
- Codeforces 796C 想法
- Codeforces 229C 想法
- Codeforces 776C 想法
- CodeForces 757 C 想法题
- codeforces 777C 想法题
- Codeforces 229C Triangles 想法题
- Codeforces Round #276 (Div. 2) C. Bits (想法)
- codeforces 3C Tic-tac-toe (想法题)
- codeforces #317 C. Lengthening Sticks (很好的想法题)
- Codeforces Alpha Round #21 C. Stripe 2 【DP+标记想法】
- codeforces 675C Money Transfers(想法题)
- codeforces round#347 div2 C International Olympiad 想法题
- Codeforces Round #377 (Div. 2)C. Sanatorium(想法题)
- 【想法】codeforces.com/contest/884/problem/C Bertown Subway
- Codeforces 763B 想法
- Codeforces 509E 想法
- Codeforces 359D 想法
- Codeforces 496D 想法
- Android JNI开发入门教程
- iframe跨域调用问题
- 第六天2017/04/11(1:结构体链表基础和相关经典操作)
- 网络流-最大流
- UVa 1585 Score / 1586 Molar Mass(遍历+计数)
- Codeforces 796C 想法
- sql注入与statement和preraredstatement关联
- BZOJ4380: [POI2015]Myjnie
- URAL1991-The battle near the swamp
- magin重叠
- Windows socket编程
- hjr-SQL-SQL 常用查询语句
- hdu1516 字符串编辑距离dp
- 如何实现浏览器当前标签是否打开或切换