• hdu 4606 Occupy Cities


    http://acm.hdu.edu.cn/showproblem.php?pid=4606

    两点之间如果有线段相隔的话,他们的最短路就需要经过线段的端点

    把所有线段的端点也加入点数组中,求任意两个点的距离(可达的话,没有其他线段阻挡)

    然后对所有的点进行floyd  可以求出任意两点的最短路

    然后二分所需容量 根据容量和要求的顺序进行建图,求最小覆盖路径(匈牙利算法)

    代码:

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<cmath>
    #include<set>
    #include<map>
    #include<stack>
    #include<vector>
    #include<algorithm>
    #include<queue>
    #include<stdexcept>
    #include<bitset>
    #include<cassert>
    #include<deque>
    #include<numeric>
    
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    
    using namespace std;
    
    typedef long long ll;
    typedef unsigned int uint;
    typedef pair<int,int> pp;
    const double eps=1e-9;
    const int INF=0x3f3f3f3f;
    const ll MOD=1000000007;
    const int N=510;
    double x[N],y[N];
    double dist[N][N];
    int schedule[N];
    bool visited[N];
    bool link[N][N];
    int f[N];
    int lr(double x1,double y1,double x2,double y2)
    {
        double tmp=x1*y2-x2*y1;
        if(abs(tmp)<eps)
        return 0;
        if(tmp>=eps)
        return 1;
        return -1;
    }
    bool dfs(int x,int n)
    {
        for(int i=x+1;i<=n;++i)
        if(link[x][i]&&!visited[i])
        {
            visited[i]=true;
            if(f[i]==-1||dfs(f[i],n))
            {
                f[i]=x;
                return true;
            }
        }
        return false;
    }
    int needSoldier(int n,double d)
    {
        memset(link,false,sizeof(link));
        for(int i=1;i<=n;++i)
        for(int j=i+1;j<=n;++j)
        if(d-dist[schedule[i]][schedule[j]]>=eps)
        link[i][j]=true;
        memset(f,-1,sizeof(f));
        int sum=0;
        for(int i=1;i<=n;++i)
        {
            memset(visited,false,sizeof(visited));
            if(dfs(i,n))
            ++sum;
        }
        return (n-sum);
    }
    double bar(int l,int r,int n,int ln)
    {
        for(int i=n+1;i<=ln;i=i+2)
        {
            double x1=x[r]-x[l];
            double y1=y[r]-y[l];
            double x2=x[i]-x[l];
            double y2=y[i]-y[l];
            int k1=lr(x1,y1,x2,y2);
            x2=x[i+1]-x[l];
            y2=y[i+1]-y[l];
            int k2=lr(x1,y1,x2,y2);
            if(k1==0||k2==0||k1==k2)
            continue;
            x1=x[i+1]-x[i];
            y1=y[i+1]-y[i];
            x2=x[l]-x[i];
            y2=y[l]-y[i];
            k1=lr(x1,y1,x2,y2);
            x2=x[r]-x[i];
            y2=y[r]-y[i];
            k2=lr(x1,y1,x2,y2);
            if(k1==0||k2==0||k1==k2)
            continue;
            return INF;
        }
        return sqrt((x[r]-x[l])*(x[r]-x[l])+(y[r]-y[l])*(y[r]-y[l]));
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        //freopen("1007.in","r",stdin);
        //freopen("my.out","w",stdout);
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int n,m,p;
            scanf("%d %d %d",&n,&m,&p);
            for(int i=1;i<=n;++i)
            scanf("%lf %lf",&x[i],&y[i]);
            int ln=n;
            while(m--)
            {
                ++ln;
                scanf("%lf %lf",&x[ln],&y[ln]);
                ++ln;
                scanf("%lf %lf",&x[ln],&y[ln]);
            }
            for(int i=1;i<=n;++i)
            scanf("%d",&schedule[i]);
            for(int i=1;i<=ln;++i)
            for(int j=i;j<=ln;++j)
            {
                if(i==j) dist[i][j]=0.0;
                else
                dist[i][j]=dist[j][i]=bar(i,j,n,ln);
            }
            for(int l=1;l<=ln;++l)
            for(int i=1;i<=ln;++i)
            for(int j=1;j<=ln;++j)
            if(dist[i][j]>dist[i][l]+dist[l][j])
            dist[i][j]=dist[i][l]+dist[l][j];
            /*
            for(int i=1;i<=n;++i)
            {
                for(int j=1;j<=n;++j)
                cout<<dist[i][j]<<" ";cout<<endl;
            }*/
            double l=0.0,r=1000000.0;
            double ep=1e-6;
            while(abs(r-l)>ep)
            {
                double mid=(l+r)/2;
                if(needSoldier(n,mid)<=p)
                r=mid;
                else
                l=mid;
            }
            printf("%.2lf
    ",r);
        }
        return 0;
    }
    
  • 相关阅读:
    Mybatis里Mapper.xml加强
    在eclipse中怎么把一个普通的项目变成一个maven项目
    给自己写博客定的小标准
    五一假期的惬意生活~
    MAC上postman离线安装时提示加载扩展程序出错怎么办?
    2017-4-6 四月生花,冷暖自知
    微信小程序开发过程中tabbar页面显示的相关问题及解决办法!
    微信小程序中如何实现分页下拉加载?(附源码)
    利用stylist插件,简单两步屏蔽新浪微博上的广告
    微信小程序官方指南手册,教你如何使用微信小程序!
  • 原文地址:https://www.cnblogs.com/liulangye/p/3215289.html
Copyright © 2020-2023  润新知