zoukankan      html  css  js  c++  java
  • 牛客 国庆七天乐 day1 L

    https://www.nowcoder.com/acm/contest/201/L

    题意:给你两条平行的直线和n个圆,在直线上面行走和在圆上和在圆内行走不需要耗费体力,除了这些区域外平面上经过任意两点需要走的距离都是欧几里得距离,求从直线1走到直线2所需要消耗的最小体力是多少。

    题解:一开始以为是计算几何,但是冷静分析了一波后发现这个题要用最短路写,建边过程有点复杂:

    1.从直线1到直线2要建边。

    2.有n<1000个点,每个圆之间都应该有边,所以n方将所有圆连接起来,记得在圆内走和在圆上走不消耗体力需要处理一下。

    3.从直线1到每个圆需要建边,从直线2到每个圆需要建边。

    tips:最后建边的条数为2*(n*n+2*n+2)条,所以要把存边的数组开到1e6

    建边完成后就简单的跑最短路就好,记得所有变量都要用double不容易出错

    代码如下:

    #include <map>
    #include <set>
    #include <cmath>
    #include <ctime>
    #include <stack>
    #include <queue>
    #include <cstdio>
    #include <cctype>
    #include <bitset>
    #include <string>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    #define PI acos(-1)
    #define eps 1e-8
    #define fuck(x) cout<<#x<<" = "<<x<<endl;
    #define FIN freopen("input.txt","r",stdin);
    #define FOUT freopen("output.txt","w+",stdout);
    //#pragma comment(linker, "/STACK:102400000,102400000")
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> PII;
    const int maxn = 1e6+5;
    const int inf = 2.1e9;
    const LL INF = 999999999999999;
    const int MOD = 1e9+7;
    LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
    LL lcm(LL a,LL b){return a/gcd(a,b)*b;}
    LL powmod(LL a,LL b,LL MOD){LL ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
    double dpow(double a,LL b){double ans=1.0;while(b){if(b%2)ans=ans*a;a=a*a;b/=2;}return ans;}
    int n;
    struct point{
        int x,y;
        int r;
        double d1,d2;
    }p[maxn];
    double Dis(point a,point b){
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    double dis1(int a,int b,int c1,int c2){
        return abs(c1-c2)/sqrt(a*a+b*b);
    }
    double dis2(int a,int b,int c,int x,int y){
        return abs(a*x+b*y+c)/sqrt(a*a+b*b);
    }
    struct node{
        int v,nxt;
        double w;
        bool operator<(const node p)const{return p.w<w;}
    }edge[maxn];
    int head[maxn];
    int tot;
    void add(int u,int v,double w){
        edge[tot].v=v;
        edge[tot].w=w;
        edge[tot].nxt=head[u];
        head[u]=tot++;
    }
    double dis[maxn];
    bool vis[maxn];
    void dij(){
        fill(dis+1, dis + n+5, inf);
        dis[n+1]=0;
        priority_queue<node>q;
        node tmp;
        tmp.v=n+1;
        tmp.w=0;
        q.push(tmp);
        while(!q.empty()){
            tmp=q.top();
            q.pop();
            if(!vis[tmp.v]){
                vis[tmp.v]=1;
                int u=tmp.v;
                for(int i=head[u];i!=-1;i=edge[i].nxt){
                    int v=edge[i].v;
                    if(dis[v]>dis[u]+edge[i].w){
                        dis[v]=dis[u]+edge[i].w;
                        tmp.w=dis[v];
                        tmp.v=v;
                        q.push(tmp);
                    }
                }
            }
        }
    }
    int main(){    
    #ifndef ONLINE_JUDGE
        FIN
    #endif
        int a,b,c1,c2;
        cin>>n>>a>>b>>c1>>c2;
        int ans=dis1(a,b,c1,c2);
        // fuck(ans);
        memset(head,-1,sizeof(head));
        tot=0;
        add(n+1,n+2,ans);
        add(n+2,n+1,ans);
        for(int i=1;i<=n;i++){
            scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].r);
            p[i].d1=max(0.0,dis2(a,b,c1,p[i].x,p[i].y)-p[i].r);
            add(n+1,i,p[i].d1);
            add(i,n+1,p[i].d1);
            p[i].d2=max(0.0,dis2(a,b,c2,p[i].x,p[i].y)-p[i].r);
            add(n+2,i,p[i].d2);
            add(i,n+2,p[i].d2);
        }
        for(int i=1;i<=n;i++){
            for(int j=i+1;j<=n;j++){
                double d=Dis(p[i],p[j]);                                       
                d=max(0.0,d-p[i].r-p[j].r);
                // fuck(d);
                add(i,j,d);
                add(j,i,d);
            }
        }
        dij();
        // for(int i=0;i<n+3;i++){
        //     printf("%10.6f
    ",dis[i]);
        // }
        printf("%.6f
    ",dis[n+2]);
    }
    View Code
    每一个不曾刷题的日子 都是对生命的辜负 从弱小到强大,需要一段时间的沉淀,就是现在了 ~buerdepepeqi
  • 相关阅读:
    Linux 文件的软连接和硬连接
    URLOS发布NFS文件加速功能,可有效提升NFS小文件读取性能
    Vue底层学习3——手撸发布订阅模式
    Vue底层学习2——手撸数据响应化
    Vue底层学习1——原理解析
    rest api测试工具frisbyjs
    git ignore 微软临时文件(~$xxx.xlsx)
    数据虚拟化-基础概念
    elasticsearch移除映射类型(mapping type)
    activemq Virtual Destinations 虚拟目的地
  • 原文地址:https://www.cnblogs.com/buerdepepeqi/p/9738703.html
Copyright © 2011-2022 走看看