• 练习备份3


    #include<set>
    #include<queue>
    #include<algorithm>
    #include<cmath>
    #include<iostream>
    #include<vector>
    using namespace std;
    const int INF = 0xFFFFFFF; 
    const int maxn = 51;
    int n,m,k;
    struct Node{
        int x,y;
        Node(){ x=y=0;}
        Node(int _x,int _y){ x=_x,y=_y;}
    };
    set<int>p[26];
    Node person[51],post[26];
    double d[26];
    bool canUse[26];
    void test(){
        for(int i=0;i<m;i++)
        if(canUse[i])
        {
            printf("邮局%d的村民有 :",i+1);
            for(set<int>::iterator it=p[i].begin();it!=p[i].end();it++) printf("%d ",*it+1);
            printf("
    总距离%lf
    ",d[i]);
        }
    }
    double dis(int index1,int index2)
    {
        Node house = person[index1];
        Node po = post[index2];
        int x1=house.x,y1=house.y;
        int x2=po.x,y2=po.y;
        double sum = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
        return sqrt(sum);
    }
    int findMinPost(int index) //找到最近的邮局的编号(可用的邮局) 
    {
        Node temp=person[index];//找到这个人的最近可用邮局
        double MIN = INF;
        int u = -1;
        for(int i=0;i<m;i++)
        {
            if(canUse[i])
            {
                if(dis(index,i)<MIN) 
                {
                    u=i;
                    MIN=dis(index,i);
                }
            }    
        }
        return u; 
    }
    int main(void)
    {
        int x,y;
        cin>>n>>m>>k;
        for(int i=0;i<n;i++)
        {
            cin>>x>>y;
            person[i].x=x,person[i].y=y;
        }
        for(int i=0;i<m;i++)
        {
            cin>>x>>y;
            canUse[i]=true;
            post[i].x=x,post[i].y=y;
        }
        for(int i=0;i<n;i++)
        {
            int pos=findMinPost(i);
            p[pos].insert(i);
        }
        for(int i=0;i<m;i++)
        {
            d[i]=0;
            for(set<int>::iterator it=p[i].begin();it!=p[i].end();it++)
            {
                d[i]+=dis(*it,i);
            }
        }
        //test
        test();
        for(int i=0;i<m-k;i++)//删除m-k个邮局 
        {
            printf("第%d次删除
    ",i+1);
            int u=-1,MIN=INF;
            for(int j=0;j<m;j++)
            if(canUse[i])
            {
                if(p[j].size()<MIN) 
                {
                    u=j,MIN=p[j].size();
                }
                else if(p[j].size()==MIN)
                {
                    if(d[j]>d[u])
                    {
                        u=j;
                        MIN=p[j].size();
                    }
                }
            }
            canUse[u]=false; 
            for(set<int>::iterator it=p[u].begin(); it != p[u].end();it++)
            {
                int pos=findMinPost(*it);
                p[pos].insert(*it);
                d[pos]+=dis(*it,pos);
            }
            test();
            printf("
    
    ");
        }
        for(int i=0;i<m;i++)
         if(canUse[i]) printf("%d ",i+1); 
        return 0;    
    } 
    </pre>AC思路(dfs+剪枝):dfs最重要的就是建立搜索树,这里每个点都有两种状态,如果直接暴力时间肯定很长,所以需要加上剪枝,我们可以将村子的住户还有备用邮局看作是两个集合,就像普利姆的思路一样,总的思路就是更新最短距离数组,我们先将所有的点全部连接在第一个备用邮局,也可以不连第一个,毕竟每个点有两种状态,如果第二个备用邮局到住户的距离足以更新最短距离数组,那就更新之后寻找下一个邮局,如果不足以更新最短距离数组,我们就直接放弃这个点,显然他是没有用的,找到k个邮局之后就判定一下话费,是否更短,如果是,更新序号数组  
    [cpp] view plaincopyprint?
    #include<iostream>    
    #include<stdlib.h>  
    #include<math.h>  
    using namespace std;  
    int n,m,k,j,c[55][2],y[27][2],d[12],f1,f2,f[55]={0};  
    float yc[27][55],s=1000000000;  
    int dfs(int t,int i,int o[12],float w[55],float sum)  
    {  
        if(i<=m+1)  
        {  
            if(t==k)
            {  
                 if(sum<s)  
                {  
                    s=sum;  
                    for(j=0;j<k;j++)  
                        d[j]=o[j];  
                }  
            }  
            else if(i<=m&&t<k)  
            {  
                float ww[55];   
                for(j=1;j<=n;j++)  
                ww[j]=w[j];
                dfs(t,i+1,o,w,sum);
                
                f1=1,f2=0;
                if(!f[i])  
                {  
                    o[t]=i;  
                    if(t>0)  
                    {  
                        f2=1;   
                        for(j=1;j<=n;j++)  
                        {  
                            if(ww[j]>yc[i][j])  
                            {  
                                sum=sum-ww[j]+yc[i][j];   
                                ww[j]=yc[i][j];  
                                f1=0;
                            }  
                        }  
                    }  
                    else  
                    {  
                        for(j=1;j<=n;j++)  
                        {  
                            sum+=yc[i][j];
                            ww[j]=w[j]=yc[i][j];  
                        }  
                    }  
                    if(f1&&f2)
                    {  
                        f[i]=1;
                        dfs(t,i+1,o,w,sum);
                    }  
                    else  
                    dfs(t+1,i+1,o,ww,sum); 
                }  
            }  
        }  
    }  
    int main()  
    {  
        int i,j,o[12];  
        float w[55],ww[55];  
        cin>>n>>m>>k;  
        for(i=1;i<=n;i++)  
        cin>>c[i][0]>>c[i][1];  
        for(i=1;i<=m;i++)  
        {  
            cin>>y[i][0]>>y[i][1];  
            for(j=1;j<=n;j++)  
            yc[i][j]=sqrt((c[j][0]-y[i][0])*(c[j][0]-y[i][0])+(c[j][1]-y[i][1])*(c[j][1]-y[i][1]));  
        }  
        dfs(0,1,o,w,0);  
        for(i=0;i<k;i++)  
        cout<<d[i]<<" ";  
        return 0;  
    }  
    /*
    #include<iostream>  
    #include<algorithm>  
    using namespace std;  
    int main()  
    {  
        int a[]={1,2,3,4,5,6};  
        sort(a,a+6);  
        do  
        {  
            for(int i=0;i<6;i++)  
                cout<<a[i];  
            cout<<endl;  
        }while(next_permutation(a,a+6));  
        return 0;  
    } 
    */
    #include<iostream>  
    #include<algorithm>  
    using namespace std;  
    int main()  
    {  
        int a[]={1,2,3,4,5,6};  
        sort(a,a+6);  
        reverse(a,a+6);  
        do  
        {  
            for(int i=0;i<6;i++)  
                cout<<a[i];  
            cout<<endl;  
        }while(prev_permutation(a,a+6));  
        return 0;  
    }   
  • 相关阅读:
    二进制数组
    model模块
    Decorator [ˈdekəreɪtə(r)] 修饰器/装饰器 -- 装饰模式
    箭头函数
    async [ə'zɪŋk] 函数
    cocos2d-x 事件分发机制 ——触摸事件监听
    算法:高速排序
    [zlib]_[0基础]_[使用Zlib完整解压zip内容]
    设计模式之状态模式(State)摘录
    编写Web Serviceclient訪问www.webxml.com.cn提供的服务
  • 原文地址:https://www.cnblogs.com/zuimeiyujianni/p/8875255.html
Copyright © 2020-2023  润新知