ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

1021 郊区春游 TSP+floyd

2022-08-03 18:36:29  阅读:181  来源: 互联网

标签:1021 郊区 int 花费 铁子 floyd dp TSP


链接:https://ac.nowcoder.com/acm/contest/25022/1021
来源:牛客网

题目描述

今天春天铁子的班上组织了一场春游,在铁子的城市里有n个郊区和m条无向道路,第i条道路连接郊区Ai和Bi,路费是Ci。经过铁子和顺溜的提议,他们决定去其中的R个郊区玩耍(不考虑玩耍的顺序),但是由于他们的班费紧张,所以需要找到一条旅游路线使得他们的花费最少,假设他们制定的旅游路线为V1, V2 ,V3 ... VR,那么他们的总花费为从V1到V2的花费加上V2到V3的花费依次类推,注意从铁子班上到V1的花费和从VR到铁子班上的花费是不需要考虑的,因为这两段花费由学校报销而且我们也不打算告诉你铁子学校的位置。

输入描述:

第一行三个整数n, m, R(2 ≤ n ≤ 200, 1 ≤ m ≤ 5000, 2 ≤ R ≤ min(n, 15))。
第二行R个整数表示需要去玩耍的郊区编号。
以下m行每行A
i
, B
i
, C
i
(1 ≤ A
i
, B
≤ n, A
≠ B
i
, C
≤ 10000)
保证不存在重边。

输出描述:

输出一行表示最小的花费
示例1

输入

复制
4 6 3
2 3 4
1 2 4
2 3 3
4 3 1
1 4 1
4 2 2
3 1 6

输出

复制
3

 

分析

最终改了inf = 0x3f3f3f3f过了。。0x7f7f7f7f都不管用

TSP类型的问题,我一开始还以为所有结点都要走,不管看了 n 的范围:200,怎么都不可能啊。最后发现是先floyd预处理处所有 目标旅游景点之间的距离,再在他们之间用 TSP。。

设dp[st] [j] 表示状态是st  ,最后一步走到j 的最短距离。

枚举 起始位置和新位置,st 满足没有新位置有起始位置就可以了

状态转移:

dp[i | (1 <<(k-1)] [k] = min(dp[i | ( 1 << (k-1)][k],dp[i][j] + a[i][j]); a表示两点最短距离。

 

//-------------------------代码----------------------------

//#define int ll
const int N = 400;
int n,m,r;
int a[N][N];
int rs[N];
int dp[1 << 20][20];
void solve()
{
    cin>>n>>m>>r;
    for(int i=1;i<=r;i++) cin>>rs[i];
    ms(a,inf);
    ms(dp,inf);
    while(m--)
    {
        int u,v,w;
        cin>>u>>v>>w;
        a[u][v]=a[v][u]=w;
    }
    for(int k=1;k<=n;k++)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++) a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
        }
    }
    for(int i=1;i<=r;i++)
    {
        dp[1<<(i-1)][i]=0; //最开始走的那一个点,是没有花费的
    }
    for(int i=1;i<(1<<r)-1;i++)//枚举状态
    {
        for(int j=1;j<=r;j++)//枚举起始位置
        {
            int jj=1<<(j-1);
            if(!(i&jj)) continue;//起始位置肯定是走过的
            for(int k=1;k<=r;k++)//枚举终止位置
            {
                int kk=1<<(k-1);
                if(i&kk) continue;//终止位置一定是一个新位置
                dp[i|kk][k]=min(dp[i|kk][k],dp[i][j]+a[rs[j]][rs[k]]);
            }
        }
    }
    int mn = inf;
    fo(i,1,r) {
        mn = min(mn,dp[(1<<r)-1][i]);
    }
    cout<<mn<<endl;
}

signed main(){
    AC();
    clapping();TLE;

//    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

标签:1021,郊区,int,花费,铁子,floyd,dp,TSP
来源: https://www.cnblogs.com/er007/p/16548193.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有