[PA2014]Budowa

题目大意:

有A和B两名候选人。共有\(n(n\le1000)\)个人参加投票。他们之间形成了一个树结构,树上的结点有两种身份:专家(叶子结点)或领导(非叶子结点)。每位专家都有自己的选择——支持A和B之中的一个;每位领导都有若干个下属(子结点),领导的选择决定于下属中人数较多的那一方,下属的数目保证为奇数,从而不会出现平局状况。最后,根结点的选择即为选举结果。

目前仍有一些专家处于犹豫未决的状态,只要前去游说,就可获得他的支持。每人每天只能选择游说一名专家。A先开始,两人交替进行,直到每位专家都有了确定的选择。请问A是否有策略保证自己赢得选举胜利?

思路:

首先,假设那些犹豫的专家最后两边都不支持,如果此时已经B占优势,那么A永远没有反超的机会了。

否则枚举每个犹豫的专家,令他支持A,剩下两边都不支持,看一下是否能使A胜利,如果能,就说明第一步可以选择这个专家。

枚举复杂度\(\mathcal O(n)\),计算支持者的复杂度\(\mathcal O(n)\),总时间复杂度\(\mathcal O(n^2)\)。可以通过此题。

实际上,本题还有一种\(\mathcal O(n\log n)\)的做法。

一开始判断是否有解的算法同上,但是可以\(\mathcal O(n)\)求出可以选择的专家。

对于一个点\(x\),若子结点中支持A的人数+\(\lceil\frac{\text{犹豫的人数}}2\rceil\ge\)支持B的人数,则说明可以选择该子树内的专家。

由于要排序,所以时间复杂度是\(\mathcal O(n\log n)\)的。

源代码:

\(\mathcal O(n^2)\):

#include<cstdio>
#include<cctype>
#include<vector>
inline int getint() {
register char ch;
register bool neg=false;
while(!isdigit(ch=getchar())) neg|=ch=='-';
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return neg?-x:x;
}
const int N=1001;
int c[N],d[N][2],ans[N];
std::vector<int> e[N];
inline void add_edge(const int &u,const int &v) {
e[u].push_back(v);
}
void dfs(const int &x,const int &par) {
//0: xyw, 1: jry
d[x][0]=d[x][1]=0;
if(c[x]<0) d[x][c[x]+2]++;
for(int i=0;i<c[x];i++) {
const int &y=e[x][i];
if(y==par) continue;
dfs(y,x);
if(d[y][1]==d[y][0]) continue;
d[x][d[y][1]>d[y][0]]++;
}
}
int main() {
const int n=getint();
for(register int i=1;i<=n;i++) {
c[i]=getint();
for(register int j=0;j<c[i];j++) {
add_edge(i,getint());
}
}
dfs(1,0);
if(d[1][1]>d[1][0]) {
puts("NIE");
return 0;
}
for(register int i=1;i<=n;i++) {
if(c[i]==0) {
c[i]=-2;
dfs(1,0);
if(d[1][0]>d[1][1]) {
ans[++ans[0]]=i;
}
c[i]=0;
}
}
printf("TAK %d\n",ans[0]);
for(register int i=1;i<=ans[0];i++) {
printf("%d%c",ans[i]," \n"[i==ans[0]]);
}
return 0;
}

\(\mathcal O(n\log n)\):

#include<cstdio>
#include<cctype>
#include<vector>
#include<algorithm>
inline int getint() {
register char ch;
register bool neg=false;
while(!isdigit(ch=getchar())) neg|=ch=='-';
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return neg?-x:x;
}
const int N=1001;
int c[N],d[N][3],ans[N];
std::vector<int> e[N];
inline void add_edge(const int &u,const int &v) {
e[u].push_back(v);
}
void dfs(const int &x,const int &par) {
//0: xyw, 1: jry
if(c[x]<=0) d[x][c[x]+2]++;
for(int i=0;i<c[x];i++) {
const int &y=e[x][i];
if(y==par) continue;
dfs(y,x);
if(d[y][1]==d[y][0]) {
d[x][2]++;
} else {
d[x][d[y][1]>d[y][0]]++;
}
}
}
void solve(const int &x,const int &par) {
if(c[x]==0) ans[++ans[0]]=x;
for(int i=0;i<c[x];i++) {
const int &y=e[x][i];
if(y==par) continue;
if(d[y][0]+1-d[y][2]%2==d[y][1]) {
solve(y,x);
}
}
}
int main() {
const int n=getint();
for(register int i=1;i<=n;i++) {
c[i]=getint();
for(register int j=0;j<c[i];j++) {
add_edge(i,getint());
}
}
dfs(1,0);
if(d[1][1]>d[1][0]) {
puts("NIE");
return 0;
}
if(d[1][1]<d[1][0]) {
for(register int i=1;i<=n;i++) {
if(c[i]==0) {
ans[++ans[0]]=i;
}
}
} else {
solve(1,0);
std::sort(&ans[1],&ans[ans[0]]+1);
}
printf("TAK %d\n",ans[0]);
for(register int i=1;i<=ans[0];i++) {
printf("%d%c",ans[i]," \n"[i==ans[0]]);
}
return 0;
}

[PA2014]Budowa的更多相关文章

  1. bzoj 3722: PA2014 Final Budowa

    3722: PA2014 Final Budowa Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 303  Solved: 108[Submit][St ...

  2. BZOJ 3721: PA2014 Final Bazarek

    3721: PA2014 Final Bazarek Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 645  Solved: 261[Submit][ ...

  3. BZOJ 3709: [PA2014]Bohater

    3709: [PA2014]Bohater Time Limit: 5 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1050  Solved: ...

  4. bzoj3714: [PA2014]Kuglarz

    [PA2014]KuglarzTime Limit: 20 Sec Memory Limit: 128 MBSubmit: 553 Solved: 317[Submit][Status][Discus ...

  5. 【贪心】bzoj 3709:[PA2014]Bohater

    3709: [PA2014]Bohater Time Limit: 5 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 653  Solved:  ...

  6. BZOJ3715: [PA2014]Lustra

    3715: [PA2014]Lustra Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 237  Solved: 149[Submit][Status ...

  7. BZOJ3709: [PA2014]Bohater

    3709: [PA2014]Bohater Time Limit: 5 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 339  Solved: ...

  8. BZOJ3713: [PA2014]Iloczyn

    3713: [PA2014]Iloczyn Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 206  Solved: 112[Submit][Status ...

  9. BZOJ 3713: [PA2014]Iloczyn( 枚举 )

    斐波那契数列<10^9的数很少很少...所以直接暴力枚举就行了... ------------------------------------------------------------- ...

随机推荐

  1. RabbitMQ队列的使用

    为什么要用RabbitMQ 以常见的订单系统为例,用户点击[下单]按钮之后的业务逻辑可能包括:扣减库存.生成相应单据.发红包.发短信通知.在业务发展初期这些逻辑可能放在一起同步执行,随着业务的发展订单 ...

  2. jieba 库的使用和好玩的词云

    jieba库的使用: (1)  jieba库是一款优秀的 Python 第三方中文分词库,jieba 支持三种分词模式:精确模式.全模式和搜索引擎模式,下面是三种模式的特点. 精确模式:试图将语句最精 ...

  3. Vue(基础八)_导航守卫(组件内的守卫)

    一.前言 主要通过一个例子演示三个钩子的作用: 1.beforeRouteEnter()                                                         ...

  4. 微信小程序之canvas 文字断行和省略号显示

    文字的多行处理在dom元素中很好办.但是canvas中没有提供方法,只有通过截取指定字符串来达到目的. 那么下面就介绍我自己处理的办法: wxml: <canvas canvas-id='wor ...

  5. Docker:dockerfile镜像的分层 [九]

    一.docker镜像的分层 1.图像呈现 2.命令呈现 [root@oldboy kod]# docker image history kod:v1 IMAGE CREATED CREATED BY ...

  6. Caused by: java.lang.ClassNotFoundException: org.springframework.web.filter.FormContentFilter

    又是一个报错,我写代码真的是可以,所有的bug都会被我遇到,所有的问题我都能踩一遍,以前上学的时候同学就喜欢问我问题,因为他们遇到的问题,我早就遇到了......... 看看报错内容: 2019-04 ...

  7. 第十六节:语法总结(3)(C#6.0和C#7.0新语法)

    一. C# 6.0 新语法 1. 自动属性初始化可以赋值 /// <summary> /// 自动属性初始化 /// </summary> public class UserI ...

  8. jQuery AJAX 方法 success()后台传来的4种数据

    JAVA中的四种JSON解析方式详解 jQuery AJAX 方法 success()后台传来的4种数据 1.后台返回一个页面 js代码 /**(1)用$("#content-wrapper ...

  9. Tuxedo 汇总

    ===================================C/S / Tuxedo 架构/ B/S 架构演进===================================Tuxed ...

  10. 菜鸟博客装饰分享CSS+HTML+js

    博客布局更改,各种百度,自己修改,搞成现在这样,有兴趣的朋友可以复制我下面的把自己博客覆盖了,然后在进行更改 不懂可加群问我:675678830 如果想开通打赏,用到js,需要在 下列中 博客侧边栏公 ...