山东理工 周赛三 第一题 dijstra

Constructing Roads

Time Limit: 1000MS Memory limit: 65536K

题目描述

    Long long ago, There was a country named X, the country has N cities which are numbered from 1 to N.
    The king of Country-X wants to construct some roads.
    Please note that Country-X is blessed by an angel. He(The angel is a boy? This is no science, but do not care about those details, this angel is so cute, he must be a boy) can use magic to make one road connections directly from two cities’ cost to be half, but the magic can only be used once.
    The king wants to know the minimal cost to construct a road between City-A and City-B. Because of there are so many cities and roads, the construction division comes to you, the only programmer he knows, for help.
You should write a program to calculate the minimal cost between City-A and City-B to help him.

输入

    There are multiple test cases.
    For each test case:
    The fist line is two integers N and M (2 <= N <= 10000 <= M <= 50000).
    Each of the following M lines contains three integers UV and W (1<= U,V<= N, 0 <= W <= 1000) . It shows that if we construct a road between the U-th city and the V-th city , the cost is W.
    The next line is two integers A and B (1<= A, B <= N).

输出

    For each test case,output one line containing the minimal cost , if there is no route from A to B , the output should contain the string “No solution” (without the quotes).

示例输入

2 1
1 2 99
1 2
4 3
1 2 312
2 3 520
3 1 999
3 4

示例输出

49
No solution

提示

  We define that the half of 100 is 50 and the half of 99 is 49.


#include<iostream>
#include<cstdio>
#include<cstring>
#include<stdio.h>
using namespace std;
const int maxn=1002;
const int INF=1<<30;
int n,m,a,b,w[maxn][maxn],dis1[maxn],dis2[maxn],vis[maxn],path[maxn];
void dijstra(int s,int *dis)
{
int i,j,mmin,res=0;
memset(vis,0,sizeof(vis));
vis[s]=1;
for(i=1; i<=n; i++)
{
dis[i]=w[s][i];
path[i]=s;
}
dis[s]=0;
path[s]=-1;
int pre=s;
for(i=1; i<=n; i++)
{
mmin=INF;
for(j=1; j<=n; j++)
{
if(!vis[j]&&dis[j]<mmin)
{
mmin=dis[j];
pre=j;
}
}
vis[pre]=1;
for(j=1; j<=n; j++)
{
if(!vis[j]&&dis[pre]+w[pre][j]<dis[j])//松弛条件判断
dis[j]=dis[pre]+w[pre][j];
path[j]=pre;
}
}
}
int main()
{
int u,v,val;
while(~scanf("%d%d",&n,&m))
{
int i,j;
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
{
w[i][j]=INF;
}
dis1[maxn]=dis2[maxn]=INF;
}
for(i=1; i<=m; i++)
{
scanf("%d%d%d",&u,&v,&val);
w[v][u]=w[u][v]=min(w[u][v],val);
}
scanf("%d%d",&a,&b);
dijstra(a,dis1);
dijstra(b,dis2);
int ans=INF;
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
{
if(i!=j&&w[i][j]!=INF)
{
if(ans>dis1[i]+dis2[j]+w[i][j]/2) ans=dis1[i]+dis2[j]+w[i][j]/2;
}
}
}
if(ans==INF)cout<<"No solution"<<endl;
else cout<<ans<<endl;
}
return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值