P6464 [传智杯 #2 决赛] 传送门

原题链接: P6464 [传智杯 #2 决赛] 传送门

题意

有 n 栋教学楼, m 条双向通行道路连接这些教学楼路径长度为w,路径不存在重边和自环,保证每个点都可以到达。现在学校想安装一对传送门,安装传送门的两点距离为0。求在最优方案下的任意点对的最短道路之和。

//获取点 目标点 路径权重。
for(int i = 0; i < m; i ++){
    	cin >> u >> to >> w;
        dp[u][to] = w;
        dp[to][u] = w; //因为是无向边所以需要两边获取。
}
//floyed算法
for(int k = 1; k <= n; k ++)
  for(int i = 1; i <= n; i ++)
	for(int j = 1; j <= n; j ++)
	  dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]);

在用Floyd算法初步得出未设置传送门的路径后,便可以开始求解。

for(int i = 1; i < n; i ++)
{
    for(int j = i + 1; j <= n; j ++){
    	res = 0;//res为设置传送门后的最短路径。
        //遍历各点。
    	for(int a = 1; a < n; a ++){
        	for(int b = a + 1; b <= n; b ++){
            	if(a != i or b != j){//因为设置传送门的两点间距离为0,所以当k==i或l==j时直接跳过
            		res += min(dp[a][b], min(dp[a][i] + dp[j][b], dp[a][j] + dp[i][b]));
                    //选择最短路径进行相加。
				}
			}      
		}
		ans = min(ans, res);//更新设置传送门后的最短的路径
   		}
}

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)

const int N = 1e5+10, inf = 0x3f3f3f3f;
const int maxn = 105;
ll dp[maxn][maxn];
ll n, m; 

int main()
{
	ios;
    cin >> n >> m;
    for(int i = 1; i <= n; i ++){
    	for(int j = 1; j <= n; j ++){
    		if(i == j) dp[i][j] = 0;
            else dp[i][j] = inf;
		}
	}
        
    ll u, to, w;
    for(int i = 0; i < m; i ++)
    {
    	cin >> u >> to >> w;
        dp[u][to] = w;
        dp[to][u] = w;
    }
    for(int k = 1; k <= n; k ++)
        for(int i = 1; i <= n; i ++)
            for(int j = 1; j <= n; j ++)
                dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]);
    ll ans = inf, res;
    for(int i = 1; i < n; i ++){
    	for(int j = i + 1; j <= n; j ++){
            res = 0;
            for(int a = 1; a < n; a ++){
            	for(int b = a + 1; b <= n; b ++){
            		if(a != i or b != j){
            			res += min(dp[a][b], min(dp[a][i] + dp[j][b], dp[a][j] + dp[i][b]));
					}
				}      
			}
			ans = min(ans, res);
        }
        
	}
        
    cout << ans << "\n";
    return 0;
}
全部评论

相关推荐

去B座二楼砸水泥地:不过也可以理解,这种应该没参加过秋招
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务