bzoj3051: [wc2013]平面图

Description

Input

Output

扫描线求出平面图的对偶图然后求最小生成树,用并查集按秩合并,以便查询两点间路径最大权

#include<stdio.h>
#include<algorithm>
#include<vector>
#include<set>
#include<cmath>
int f[200007],f2[200007],h2[200007];
int get(int*f,int x){
    int a=x,c;
    while(x!=f[x])x=f[x];
    while(x!=f[a])c=f[a],f[a]=x,a=c;
    return x;
}
int get2(int x){
    while(x!=f2[x])x=f2[x];
    return x;
}
void merge(int a,int b){
    a=get(f,a);b=get(f,b);
    if(a<b)f[b]=a;
    else f[a]=b;
}
double X;
struct ln{
    double k,b;int id;
    double operator()(double x)const{return k*x+b;}
    bool operator<(ln w)const{return operator()(X)+1e-8<w(X);}
};
std::set<ln>line;
struct pos{
    double x,y;
    void R(){
        scanf("%lf%lf",&x,&y);
    }
}ps[100007],qs[100007][2];
struct dir{
    double d;
    int i1,i2;
    bool operator<(dir w)const{return d<w.d;}
};
std::vector<dir>vs[100007];
struct ev{
    int t;
    double x;
    int w;
    bool operator<(ev a)const{return x!=a.x?x<a.x:t<a.t;}
}e[500007];
int ep=0,ee[200007];
int n,m,q;
struct edge{
    int a,b,c,ID;
    ln l;
    void R(int I){
        ID=I;
        scanf("%d%d%d",&a,&b,&c);
        if(ps[a].x>ps[b].x)std::swap(a,b);
        if(ps[a].x!=ps[b].x){
            e[ep++]=(ev){1,ps[a].x,I};
            e[ep++]=(ev){0,ps[b].x,I};
            double k=(ps[b].y-ps[a].y)/(ps[b].x-ps[a].x);
            l=(ln){k,ps[a].y-ps[a].x*k,I};
        }
        vs[a].push_back((dir){atan2(ps[b].y-ps[a].y,ps[b].x-ps[a].x),I,I+m});
        vs[b].push_back((dir){atan2(ps[a].y-ps[b].y,ps[a].x-ps[b].x),I+m,I});
    }
    bool operator<(const edge&w)const{return c<w.c;}
}es[100007];
int ws[100007][2];
void maxs(int&a,int b){if(a<b)a=b;}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m*2;++i)f[i]=f2[i]=i;
    for(int i=1;i<=n;++i)ps[i].R();
    for(int i=1;i<=m;++i)es[i].R(i);
    scanf("%d",&q);
    for(int i=1;i<=q;++i){
        qs[i][0].R();
        qs[i][1].R();
        e[ep++]=(ev){2,qs[i][0].x,i};
        e[ep++]=(ev){3,qs[i][1].x,i};
    }
    std::sort(e,e+ep);
    e[ep].x=e[ep-1].x+10000;
    double x0=e[0].x-10000,x1;
    for(int i=0,j=0;i<ep;){
        x1=e[i].x;
        for(;j<ep&&e[j].x==x1;++j);
        X=(x0+x1)/2.;
        for(;i<j&&e[i].t==0;++i){
            std::set<ln>::iterator it=line.find(es[e[i].w].l);
            line.erase(it);
        }
        X=(x1+e[j].x)/2.;
        for(int k=i;k<j&&e[k].t==1;++k){
            ln w=es[e[k].w].l;
            line.insert(w);
        }
        for(;i<j&&e[i].t==1;++i){
            ln w=es[e[i].w].l;
            std::set<ln>::iterator it=line.find(w);
            ++it;
            if(it==line.end())merge(0,e[i].w+m);
            else merge(e[i].w+m,it->id);
            --it;
            if(it==line.begin())merge(0,e[i].w);
            else --it,merge(e[i].w,it->id+m);
        }
        X=x1;
        for(;i<j;++i){
            ln w=(ln){0,qs[e[i].w][e[i].t-2].y,0};
            std::set<ln>::iterator it=line.lower_bound(w);
            if(it!=line.end())ws[e[i].w][e[i].t-2]=it->id;
        }
        x0=x1;
    }
    for(int i=1;i<=n;++i)if(!vs[i].empty()){
        std::sort(vs[i].begin(),vs[i].end());
        vs[i].push_back(vs[i][0]);
        for(int j=1;j<vs[i].size();++j){
            merge(vs[i][j-1].i2,vs[i][j].i1);
        }
    }
    std::sort(es+1,es+m+1);
    for(int i=1;i<=m;++i){
        int x=get2(get(f,es[i].ID));
        int y=get2(get(f,es[i].ID+m));
        if(x&&y&&x!=y){
            if(h2[x]<h2[y])f2[x]=y,ee[x]=es[i].c;
            else{
                if(h2[x]==h2[y])++h2[x];
                f2[y]=x;ee[y]=es[i].c;
            }
        }
    }
    for(int i=1;i<=q;++i){
        int x=get(f,ws[i][0]),y=get(f,ws[i][1]);
        if(!x||!y)puts("-1");
        else{
            int v=0;
            while(x!=y){
                if(h2[x]>h2[y])std::swap(x,y);
                maxs(v,ee[x]);
                x=f2[x];
            }
            printf("%d\n",v);
        }
    }
    return 0;
}
时间: 2024-10-22 10:41:18

bzoj3051: [wc2013]平面图的相关文章

BZOJ 4541: [Hnoi2016]矿区 平面图转对偶图+DFS树

4541: [Hnoi2016]矿区 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 433  Solved: 182[Submit][Status][Discuss] Description 平面上的矿区划分成了若干个开发区域.简单地说,你可以将矿区看成一张连通的平面图,平面图划分为了若 干平面块,每个平面块即为一个开发区域,平面块之间的边界必定由若干整点(坐标值为整数的点)和连接这些整点 的线段组成.每个开发区域的矿量与该开发区域的面积有关:具

bzoj 1001: [BeiJing2006]狼抓兔子 平面图最小割

平面图跑最大流 可以转换为其对偶图跑最短路 一个环对应一个割  找到最小环(即最短路)极为所求,注意辅助边的建立 加入读入优化  不过时间还是一般  估计是dij写的不好   大神勿喷~~~ /************************************************************** Problem: 1001 User: 96655 Language: C++ Result: Accepted Time:1724 ms Memory:95120 kb ****

BZOJ 2007 海拔(平面图最小割-最短路)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2007 题意:给出一个n*n的格子,那么顶点显然有(n+1)*(n+1)个.每两个相邻顶点之间有两条边,这两条边是有向的,边上有权值..左上角为源点,右下角为汇点,求s到t的最小割. 思路:很明显这是一个平面图,将其转化为最 短路.我们将s到t之间连一条边,左下角为新图的源点S,右上角区域为新图的终点T,并且为每个格子编号.由于边是有向的,我们就要分析下这条边应该是哪 个点向哪个点的边.

[bzoj1001][BeiJing2006]狼抓兔子-题解[平面图最小割转最短路]/[Dinic求最小割]

Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: 左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路

【平面图最小割】BZOJ2007-[NOI2010]海拔

[题目大意] 城市被东西向和南北向的主干道划分为n×n个区域,包括(n+1)×(n+1)个交叉路口和2n×(n+1)条双向道路.现得到了每天每条道路两个方向的人流量.每一个交叉路口都有海拔,每向上爬h的高度,就需要消耗h的体力.如果是下坡的话,则不需要耗费体力.城市西北角的交叉路口海拔为0,东南角的交叉路口海拔为1.现在知道每条路两个方向的人流量,在最理想的情况下(即你可以任意假设其他路口的海拔高度),求每天所有人爬坡所消耗的总体力和的最小值. [思路] 显然是一个平面图最小割,最基础的平面图最

BZOJ_1001_狼抓兔子(平面图求最小割+对偶图求最短路)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1001 分析 平面图求最小割,转化成对偶图求最短路,经典. 注意: 1.优先队列是个大根堆. 2.Dijkstra可以带一个vis数组,也可以不带,因为一个点出来以后,它更新的的点和原本就在队列里的点都比它大,所以它不可能被更新得更小,之后这个点再出队时情况不比第一次更优,所以出队也不会有操作. 3.双向边,数组要开够(貌似不是第一次犯这个错误). 4.网上有人说m==1||n==1的情况可以

平面图最小割 对偶图

平面图最小割 对偶图: 平面图G的性质: (1)满足n个点,m条边,f个面 f = m - n + 2; (2)存在与其对应的对偶图G*; 对偶图:将原图中每个面变成一个点,外边界的无限大的面看成一个点,后连线即成对偶图: G的面数等于G*的点数,边数相等: 详解请看 最大最小定理(平面图最小割 对偶图)周冬 对于平面图的最大流(最小割)只需转化为对偶图,直接跑最短路即可: ps:觉得建图是最复杂的,各种RE(边数就是原来的边数,只是点数变成了原来的面数,,不注意就RE了):还有现在行数列数都变

WC2013 糖果公园

COGS 1817. [WC2013]糖果公园 http://www.cogs.pro/cogs/problem/problem.php?pid=1817 ★★★☆   输入文件:park.in   输出文件:park.out   简单对比时间限制:8 s   内存限制:512 MB [题目描述] Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园玩. 糖果公园的结构十分奇特,它由 n 个游览点构成,每个游览点

[bzoj 3052][wc2013]糖果公园

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3052 [wc2013]糖果公园 Time Limit: 200 Sec  Memory Limit: 512 MBSubmit: 1213  Solved: 609[Submit][Status][Discuss] Description Input Output Sample Input Sample Input Sample Output 84 131 27 84 树上莫队,把树分块,