zoukankan      html  css  js  c++  java
  • CodeForces

    题目链接

    题目大意

      给你一个完全图,求一个长度为k的最短路径,这个路径的起点和终点都是1,其中可以有重复访问的点和边,但是不能有奇数环。

    解题思路

      不能有奇数环,说明走的路线得是一个二分图,我们把整个图黑白染色,染成一个二分图之后进行dp,用dp[i][j]表示走了i条路线最终走到了j的最短路,dp的起点为dp[0][1],最后求dp[k][1]即为答案。
      但是一个图的二分图染色的方案是很多的,不可能全部枚举一遍。这就是这个题的有趣之处,因为最大n=80,k=10,所以最优解的路径中最多有9个点,那么我们染的颜色和最优解不一样的概率是(frac{511}{512}),我们给他染上10000次(就是这么暴力),那么其中最优方案不是答案的概率是(frac{511}{512} ^ {10000}),可以看到机率非常小,所以说几乎不可能失败。

    代码

    const int maxn = 1e2+10;
    ll g[maxn][maxn], dp[maxn][maxn];
    int c[maxn];
    int main() {
        IOS;
        int n, m; cin >> n >> m;
        for (int i = 1; i<=n; ++i) 
            for (int j = 1; j<=n; ++j) {
                cin >> g[i][j];
            }
        int __ = 1e4;
        mt19937 rand(time(0));
        ll ans = 2e18;
        while(__--) {
            for (int i = 1; i<=n; ++i) c[i] = rand()%2;
            clr(dp, 0x3f);
            dp[0][1] = 0;
            for (int i = 1; i<=m; ++i)
                for (int j = 1; j<=n; ++j)
                    for (int k = 1; k<=n; ++k)
                        if (c[j]!=c[k]) dp[i][j] = min(dp[i][j], dp[i-1][k]+g[k][j]);
            ans = min(ans, dp[m][1]);
        }
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    bootstrap的引用和注意事项
    css样式表的知识点总结
    数据去重宏脚本
    redis总结
    list对象中根据两个参数过滤数据
    dt常用类
    C#删除字符串最后一个字符的几种方法
    C#的split分割的举例
    数据库优化的几个注意点
    两种转换城市的方式
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/15348350.html
Copyright © 2011-2022 走看看