正规、严谨、精妙。 -POI

  发现POI(波兰信息学奥赛)的题都很有意思。于是开刷bzoj上的poi题目(按ac人数降序。。)。顺手写一写题解,加深印象。
  为了防止一篇文章过于长,打算每五道题另起一篇文章。


  BZOJ 1103 : [POI2007]大都市meg

  给一棵树,每次可以把树上的一些边标记了,问一个点与根之间需要走多少没有标记的边。

  这个可以把这颗树遍历得到一个dfs序每第一次经过一个点的时候记录为+1,第二次经过一个点的时候记录为-1,然后记录每个点第一次经过时在序列里的位置f[i]和第二次经过在序列里的位置l[i],对于查询(x)就是序列中一直到f[x]-1的前缀和,因为真正没走的那些边都+1-1消掉了,只剩下真正要统计的边了。对于每次标记(a,b) 设a<b 就是序列里 f[b]的位置-1,l[b]的位置+1,就相当于消掉了这条边。另外这道题得手写栈dfs,否则会爆栈。

/**************************************************************
    Problem: 1103
    User: zrts
    Language: C++
    Result: Accepted
    Time:4484 ms
    Memory:9596 kb
****************************************************************/

#include<cstdio>
#include<cstring>
#include<algorithm>
#define lowbit(x) (x&-x)
//by zrt
//problem:
using namespace std;
typedef long long ll;
);
int n,m;
];
],P[],X[],tot;
],l[];
];
int tim;
],top;
void add(int pos,int x){
    for(;pos<=n;pos+=lowbit(pos)){
        c[pos]+=x;
    }
}
int ask(int pos){
    ;
    ;pos-=lowbit(pos)){
        ret+=c[pos];
    }
    return ret;
}
inline void Add(int x,int y){
    P[++tot]=y;X[tot]=H[x];H[x]=tot;
}
int main(){
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    scanf("%d",&n);
    ,x,y;i<n;i++){
        scanf("%d%d",&x,&y);
        if(x<y) Add(x,y);
        else Add(y,x);
    }
    stk[top++]=;
    int k;
    ){
        k=stk[--top];
        if(f[k]){
            l[k]=++tim;
            c[tim]=-;
            continue;
        }else{
            f[k]=++tim;
            c[tim]=;
            stk[top++]=k;
            for(int i=H[k];i;i=X[i]){
                stk[top++]=P[i];
            }
            continue;
        }
    }
    n*=;
    ;i<n;i++){
        if(i+lowbit(i)<=n){
            c[i+lowbit(i)]+=c[i];
        }
    }
    scanf("%d",&m);
    m=n/+m-;
    ,x,y;i<m;i++){
        scanf("%s",s);
        ]=='W'){
            scanf("%d",&x);
            printf();
        }else{
            scanf("%d%d",&x,&y);
            if(x>y){
                add(f[x],-);
                add(l[x],);
            }else{
                add(f[y],-);
                add(l[y],);
            }
        }
    }
    ;
}

  BZOJ 1121 : [POI2008]激光发射器SZK

  刚看完觉得不可做。
  因为光线都是沿45°,所以从一个点发射光线必有一个点接收,又因为光路是可逆的,不可能有不同的点出发的光路重合的现象,所以输出n/2(原题让输出方案。。);

/**************************************************************
    Problem: 1121
    User: zrts
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:804 kb
****************************************************************/

#include<cstdio>
#include<cstring>
#include<algorithm>
//by zrt
//problem:
using namespace std;
typedef long long ll;
);

int main(){
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    int n;
    scanf("%d",&n);
    printf();
    ;
}

  BZOJ 1113 : [Poi2008]海报PLA

  显然单调栈啊,相等的时候处理一下。没了。

/**************************************************************
    Problem: 1113
    User: zrts
    Language: C++
    Result: Accepted
    Time:1496 ms
    Memory:1780 kb
****************************************************************/

#include<cstdio>
#include<cstring>
#include<algorithm>
//by zrt
//problem:
using namespace std;
typedef long long ll;
);
],top;
int main(){
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    int n;
    scanf("%d",&n);
    ;
    ,x;i<n;i++){
        scanf("%*d%d",&x);
        &&x<=stk[top-]) {
            top--,ans++;
            if(stk[top]==x) ans--;
        }
        stk[top++]=x;
    }
    printf("%d\n",ans+top);
    ;
}

  BZOJ 1529 : [POI2005]ska Piggy banks

  一堆存钱罐,每个存钱罐的钥匙在另一个存钱罐里,问最少砸烂多少个存钱罐。
  如果A罐的钥匙在B罐里,我们连边B->A,表示只要开了B就能开A。然后得到一张无向图,显然在一个强连通分量中的罐子最多只用砸烂一个,而每个强连通分量的罐子有可能被别的强连通分量的罐子打开,所以将这张图缩点,得到一个DAG,显然我们只用砸那些入度为0的强连通分量并且每个分量砸一个就ok了,也就是DAG的叶子节点。
(原来tarjan中,dfn没有记录的必要啊,详见程序。)

/**************************************************************
    Problem: 1529
    User: zrts
    Language: C++
    Result: Accepted
    Time:2316 ms
    Memory:63620 kb
****************************************************************/

#include<cstdio>
#include<cstring>
#include<algorithm>
//by zrt
//problem:
using namespace std;
typedef long long ll;
);
int n;
],X[],P[],tot;
inline void add(int x,int y){
    P[++tot]=y;X[tot]=H[x];H[x]=tot;
}
],stk[],top;
];
int cnt;
];
void tarjan(int x){
    int dfn=low[x]=++tim;
    instack[x]=;stk[top++]=x;
    for(int i=H[x];i;i=X[i]){
        if(!low[P[i]]) tarjan(P[i]),low[x]=min(low[x],low[P[i]]);
        else if(instack[P[i]]) low[x]=min(low[x],low[P[i]]);
    }
    if(low[x]==dfn){
        cnt++;
        int k;
        do{
            k=stk[--top];
            instack[k]=;
            belong[k]=cnt;
        }while(k!=x);
    }
}
];
int main(){
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    scanf("%d",&n);
    ,x;i<=n;i++){
        scanf("%d",&x);
        add(x,i);
    }
    ;i<=n;i++){
        if(!low[i]) tarjan(i);
    }
    ;i<=n;i++){
        for(int j=H[i];j;j=X[j]){
            ;
        }
    }
    ;
    ;i<=cnt;i++){
        if(!ind[i]) ot++;
    }
    printf("%d\n",ot);
    ;
}

  BZOJ 1532 : [POI2005]Kos-Dicing

  网络流里这个模型太熟了。
  首先求最大值最小先二分,然后判定是否可以相互制约使得都在ans场内决出冠军。具体连边就是S向每场比赛连边容量为1,每场比赛向两个人分别连边,容量1。然后每个人向T连边,容量为ans。看看最大流S是否满载。搞定。

/**************************************************************
    Problem: 1532
    User: zrts
    Language: C++
    Result: Accepted
    Time:576 ms
    Memory:2764 kb
****************************************************************/

#include<cstdio>
#include<cstring>
#include<algorithm>
//by zrt
//problem:
using namespace std;
typedef long long ll;
);
int n,m;
],X[],P[],flow[],d[],tot;
],h,t;
],b[];
int S,T;
inline void add(int x,int y,int z){
    P[++tot]=y;X[tot]=H[x];H[x]=tot;flow[tot]=z;
}
bool bfs(){
    memset(d,,;
    d[S]=;q[t++]=S;
    int k;
    while(h!=t){
        k=q[h++];
        for(int i=H[k];i;i=X[i]){
            &&(!d[P[i]])){
                q[t++]=P[i];
                d[P[i]]=d[k]+;
            }
        }
    }
    return d[T];
}
int dfs(int x,int a){
    ||x==T) return a;
    int f=a,tmp;
    for(int i=H[x];i&&a;i=X[i]){
        &&flow[i]>){
            tmp=dfs(P[i],min(a,flow[i]));
            a-=tmp;
            flow[i]-=tmp;
            flow[i^]+=tmp;
        }
    }
    ;
    return f-a;
}
int dinic(){
    );
    while(bfs()){
        f+=dfs(S,<<);
    }
    return f;
}
bool judge(int x){
    memset(H,,;
    ;i<m;i++){
        add(S,i,);add(i,S,);
        add(i,a[i]+m,);add(a[i]+m,i,);
        add(i,b[i]+m,);add(b[i]+m,i,);
    }
    ;i<=n;i++) add(i+m,T,x),add(T,i+m,);
    if(dinic()>=m) return true;
    else return false;
}
int main(){
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    scanf("%d%d",&n,&m);
    ;i<m;i++){
        scanf("%d%d",&a[i],&b[i]);
    }
    ),R(m),M;
    S=,T=;
    ){
        M=(L+R)>>;
        if(judge(M)){
            R=M;
        }else L=M;
    }
    printf("%d\n",R);
    ;
}

以上。

[原博客] POI系列(1)的更多相关文章

  1. [原博客] POI系列(3)

    正规.严谨.精妙. -POI BZOJ 1131 : [POI2008]Sta 树形dp吧,让求找一个点使以这个点深度和最小.首先可以随便整出来一棵树,对于每个节点记录down[i]以i为根下面的点的 ...

  2. [原博客] POI系列(5)

    正规.严谨.精妙. -POI BZOJ 2213 : [Poi2011]Difference 如果我们每次枚举两个字母最大最小情况时,很容易想到写出代码里注释的样子.这样是26*26*n的,我们发现枚 ...

  3. [原博客] POI系列(4)

    正规.严谨.精妙. -POI BZOJ 1531 : [POI2005]Bank notes 裸的背包,可以二进制拆分一下.一个物品比如说有n个,可以拆成 1,2,4,8,16...个. OJ上没有样 ...

  4. [原博客] POI系列(2)

    正规.严谨.精妙. -POI bzoj 1098 : [POI2007]办公楼biu 如果把互相有手机号的建边得到一个无向图,那么这个图的补图的连通分量个数就是答案了.因为互相没手机号的必然在同一个连 ...

  5. 原博客地址http://blog.chinaunix.net/uid/20656672.html弃用

    原博客地址http://blog.chinaunix.net/uid/20656672.html弃用

  6. [原博客] BZOJ 2242 [SDOI2011] 计算器

    题目链接 noip级数论模版题了吧.让求三个东西: 给定y,z,p,计算`Y^Z Mod P` 的值. 给定y,z,p,计算满足`xy≡ Z ( mod P )`的最小非负整数. 给定y,z,p,计算 ...

  7. 【全网最全的博客美化系列教程】08.自定义地址栏Logo

    全网最全的博客美化系列教程相关文章目录 [全网最全的博客美化系列教程]01.添加Github项目链接 [全网最全的博客美化系列教程]02.添加QQ交谈链接 [全网最全的博客美化系列教程]03.给博客添 ...

  8. 原博客地址http://blog.chinaunix.net/uid/20656672.html不再维护(10年前数百篇oracle/teradata性能优化、故障处理案例)

    原博客地址http://blog.chinaunix.net/uid/20656672.html不再维护(数百篇oracle/teradata性能优化.故障处理原创文章) 858871 top 500 ...

  9. 【全网最全的博客美化系列教程】01.添加Github项目链接

    全网最全的博客美化系列教程相关文章目录 [全网最全的博客美化系列教程]01.添加Github项目链接 [全网最全的博客美化系列教程]02.添加QQ交谈链接 [全网最全的博客美化系列教程]03.给博客添 ...

随机推荐

  1. input 的 placeholder属性在IE8下的兼容处理

    placeholder是input标签的新属性,在使用的时候有两个问题: 1.IE8 下不兼容 处理思路: 如果浏览器不识别placeholder属性,给input添加类名placeholder,模仿 ...

  2. JAVA_基础面试题

    1.面向对象的特征有哪些方面   1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节.抽 ...

  3. virtualization-vs-containerization

    http://containerz.blogspot.com/2015/03/virtualization-vs-containerization.html Virtualization vs. Co ...

  4. Maven 私服的使用实战

    本日志主要是介绍下面的配置 1. 将内部构件部署到私服 在工程的pom文件中添加下面配置 <distributionManagement> <repository> <i ...

  5. Spring中整合Titles

    在<Spriing实战(第三版)>这本书中,有一个使用titles的例子,但是这是一个不完整的例子.那么要参照起来就比较难了,于是找到了下面这篇博客. 在Spring中使用tiles2 ( ...

  6. 开源织梦(dedecms)快速搬家图文教程

    前段时间在seowhy班级群里,一个同学问织梦程序怎么搬家,好多人都遇到过这样的问题,不知道怎么去处理,今天小编分享一个简单的方法,帮大家快速搬家织梦. 好了,废话留到最后再说,看下面方法: 1. 登 ...

  7. OC-手动内存管理

    一.为什么要进行内存管理 •移动设备的内存极其有限,每个app所能占用的内存是有限制的 • •下列行为都会增加一个app的内存占用 Ø创建一个OC对象 Ø定义一个变量 Ø调用一个函数或者方法 • •当 ...

  8. 【转帖】客户端通过 HTTP 请求和响应 的 Header 信息总结

    请求Header原帖地址:http://technique-digest.iteye.com/blog/1174581 响应Header原帖地址:http://blog.pfan.cn/hurongl ...

  9. 【笔记】mongodb启动不了:child process failed, exited with error number 100

    今天在启动mongodb的时候,发现起不来,报错:child process failed, exited with error number 100然后先去/var/log/mongo/mongod ...

  10. 【制作镜像】virsh

    首先进入到图形界面 常用virsh指令: 1)virsh list 列出当前虚拟机列表,不包括未启动的 2)virsh list --all 列出所有虚拟机,包括所有已经定义的虚拟机 3)virsh ...