• 2013-2014 ACM-ICPC Pacific Northwest Regional Contest B.Bones’s Battery


    题意略。

    思路:

    这个题目求的是第一个可行解,由此想到用二分试探的方式来解决。

    现在讲讲怎么验证该解是否合理:

    先用floyd求出两两之间的最短距离。

    dp[ i ][ j ]表示,i 到 j 至少要充几次电,如果dist[ i ][ j ] <= 当前规定的试探值,那么令dp[ i ][ j ] = 1,否则赋值为INF,表示不知道要充几次电,

    这个要靠第二次Floyd来更新。在第二次跑完Floyd之后,看dp数组中的最大值,如果最大值小于k,那么说明合法。

    详见代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL F = 0x3f;
    
    LL dist[105][105];
    LL dp[105][105];
    int n,k,m;
    
    void init(){
        memset(dist,F,sizeof(dist));
        memset(dp,F,sizeof(dp));
    }
    
    void floyd1(){
        for(int i = 0;i < n;++i)
            dist[i][i] = 0;
        for(int k = 0;k < n;++k)
            for(int i = 0;i < n;++i)
                for(int j = 0;j < n;++j)
                    dist[i][j] = min(dist[i][j],dist[i][k] + dist[k][j]);
    }
    
    void floyd2()
    {
        for(int i = 0;i < n;++i)
            dp[i][i]=0;
        for(int k = 0;k < n;++k)
            for(int i = 0;i < n;++i)
                for(int j = 0;j < n;++j)
                    dp[i][j] = min(dp[i][j],dp[i][k] + dp[k][j]);
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
    
            scanf("%d%d%d",&n,&k,&m);
            init();
            int u,v,d;
            for(int i = 0;i<m;i++)
            {
                scanf("%d%d%d",&u,&v,&d);
                dist[u][v] = dist[v][u] = d;
            }
            floyd1();
            LL l = 1,r = INF;
            LL ans = r;
            LL mid;
            while(l <= r)
            {
                mid = (l + r)>>1;
                for(int i = 0;i < n;++i)
                    for(int j = 0;j < n;++j)
                        dp[i][j] = dist[i][j] <= mid ? 1 : INF;
                floyd2();
                LL d = 0;
                for(int i = 0;i < n;++i)
                    for(int j = 0;j < n;++j)
                        if(dp[i][j] > d) d = dp[i][j];
                if(d <= k){
                    ans = mid;
                    r = mid - 1;
                }
                else{
                    l = mid + 1;
                }
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    Android框架种类
    ASP.NET MVC 入门系列教程
    Jquery相关总结
    使用EF To Linq执行类似sql的in语句
    C#通过执行sql语句的方式执行存储过程,得到输出参数
    C#通过webapi中转上传文件到文件服务器
    sql中去除重复的数据
    web打印
    NPOI导出数据,设置格式,锁定单元格
    Uncaught SyntaxError: Invalid or unexpected token
  • 原文地址:https://www.cnblogs.com/tiberius/p/9382126.html
Copyright © 2020-2023  润新知