• uva 10985 Rings'n'Ropes


    题意:有n个铁环用长度均为1的绳子连起来(不会有重边)。试图拿起两个铁环并在水平方向拉直,那么会有一些边会被拉直(可想而知有些绳子不会被拉直而是弯曲的),那么取哪两个铁环并拉直,能使被拉直的直线最多呢?输出最多的边数

    这题其实是最短路,而且通过这题可以帮助我们更形象地理解最短路的实质尤其理解松弛操作

    当两个点a,b被拉直,那么其实那些被拉直的边就是最短路径(从a出发到b,或者反过来也行,因为是无向图),也就是说,要找到所有的最短路径并统计有多少条不同的边(因为不同的最短路径可能共用相同的边),那么就是这两点的数目,我们只要枚举任意两个点被拉直时不同边的数目,并找到最大的那个就可以了。

    所以要先知道任意两个点的最短路,floyd,然后就是dfs搜索所有可能的边,dfs搜索的时候直接使用floyd之后的d数组,并且这个我写的这个dfs感觉有点像DP记忆化搜索,因为当初想这个问题的时候就想到找不同的边用DP去做,但没想出来,然后YY了一个DFS,WA了几次终于是过,才发现挺像记忆化搜索的

    直接看代码的注释吧

    #include <cstdio>
    #include <cstring>
    #define INF 0x3f3f3f3f
    #define N 130
    int d[N][N],vis[N][N];
    int n,m,ccount,max;
    
    void input()
    {
        scanf("%d%d",&n,&m);
        memset(d,0x3f,sizeof(d));
        for(int i=1; i<=m; i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            d[u][v]=d[v][u]=1;
        }
        return ;
    }
    void floyd()
    {
        for(int k=0; k<n; k++)
            for(int i=0; i<n; i++)
                for(int j=0; j<n; j++)
                    {
                        if(d[i][k]+d[k][j]<d[i][j])
                            d[i][j]=d[i][k]+d[k][j];
                    }
        for(int i=0; i<n; i++) d[i][i]=0;
        return ;
    }
    void dfs(int sp,int len,int t ,int u) //sp为最短路值,len为当前找到的长度,t是终点,u是当前的点
    {
        if(u==t) return ;
        for(int v=0; v<n; v++) if(v!=u && d[u][v]==1 && !vis[u][v])
            if(len+d[u][v]+d[v][t]==sp)
            {
                ccount++;
                vis[u][v]=vis[v][u]=1;
                dfs(sp,len+d[u][v],t,v);
            }
        return ;
    }
    void solve()
    {
        max=0;
        for(int s=0; s<n; s++)  //枚举所有的起点和终点
            for(int t=s+1; t<n; t++) //因为是无向图,所以j=s+1开始
            {
                memset(vis,0,sizeof(vis));
                ccount=0;
                if(d[s][t]==1)  //某些最短路直接相连为1,不用搜索直接判断
                { if(max<1) max=1; continue; }
                
                dfs(d[s][t],0,t,s);
                //printf("顶点%d  %d:%d\n",s,t,ccount);
                if(ccount>max)
                    max=ccount;
            }
    }
    void print_graph()
    {
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
                printf("%d ",d[i][j]);
            printf("\n");
        }
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        for(int c=1; c<=T; c++)
        {
            input();
            //print_graph();
            floyd();
            //print_graph();
            solve();
            printf("Case #%d: %d\n",c,max);
        }
        return 0;
    }
  • 相关阅读:
    【视频开发】ONVIF、RTSP/RTP、FFMPEG的开发实录
    【视频开发】ONVIF、RTSP/RTP、FFMPEG的开发实录
    【视频开发】opencv不能读取MP4格式文件
    CentOS 7下升级Python版本到3.x系列
    PyCharm常用快捷键
    ASCII、Unicode和UTF-8编码的区别
    配置Windows Server 2008/2012/2016允许2个用户同时远程桌面
    一道简单的python面试题-购物车
    Linux 下查看局域网内所有主机IP和MAC
    CentOS 7 配置HTTPS加密访问SVN
  • 原文地址:https://www.cnblogs.com/scau20110726/p/2815263.html
Copyright © 2020-2023  润新知