201609-4 | |
试题名称: | 交通规划 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 G国国王来中国参观后,被中国的高速铁路深深的震撼,决定为自己的国家也建设一个高速铁路系统。 输入格式 输入的第一行包含两个整数n, m,分别表示G国城市的数量和城市间铁路的数量。所有的城市由1到n编号,首都为1号。 输出格式 输出一行,表示在满足条件的情况下最少要改造的铁路长度。 样例输入 4 5 样例输出 11 评测用例规模与约定 对于20%的评测用例,1 ≤ n ≤ 10,1 ≤ m ≤ 50; |
此题 不用 最小生成树的原因是 要保证条件 x 所有点到 1号点(首都点)的 最短距离不变, 此题要求满足 条件x的最小生成树
因此 此题在跑dij时 定义一个 num[i]数组存储到每个点的最短距离 , 当dis[i]确定后, 就将num[i]中的值相加 最终得到的点就是最终答案.
此题 用邻接矩阵 会运行错误(应该是空间太大)
c++通过vector创建邻接表
邻接矩阵 a 和邻接表 b —>
1 a的下标是from b的下标也代表from
2 a[i][ ]代表from i to j(j 属于 n(包括未与i顶点连接的的边)j就代表被连接的顶点编号,如果没有连接则用inf(无穷大)表示) 对应的是 b[i][j].(j属于(0,存在与顶点 i 相连的边的数量)) to(to代表被连接的顶点号)
3. a[i][] 的值为权值大小 与 b[i][].cost对应(前提与i相连的顶点存在)
4.c++邻接表的vector二维定义 vector<Edge> edge[10005];
此题思路:
因为要使每个顶点到1号点的最短距离不变 因此采用dijkstra算法,
要求出最短 修路 距离 求每个点到 1号点的最短距离 并相加,但是会遇到多个最短路径(如果dis[ u ] + edge[ u ][ i ] ==dis[ i ] ),此时定义一个数组cost[ i ] 存放到i个结点的最短距离, 如果此时比较cost[ i ] > edge[ u ][ i ](虽然i 点到1号点 最短路径相同但存 在 到 i 点 更 短 的 距 离 ) 此时改变cost[ i ] =edge[ u ] [ i ] 最后将cost数组中的值相加就是到 i 点的最短距离
邻接矩阵实现(会报错):
#include<bits/stdc++.h>
using namespace std;
const int inf=999999;
const long long maxsize=10000;
bool visit[maxsize];
int dis[maxsize];
int edge[maxsize][maxsize];
int num[maxsize];
int n,m,sum;
void dijkstra(int start){
dis[start]=0;
for(int i=1;i<=n;i++){
int min=inf,u=-1;
for(int j=1;j<=n;j++){
if(dis[j]<min && visit[j]==false){
min=dis[j];
u=j;
}
}
if(min==inf) return;
visit[u]=true;
sum+=num[u];
for(int k=1;k<=n;k++){
if(visit[k] == false && edge[u][k]!=inf){
if(dis[u]+edge[u][k]<dis[k]){
dis[k]=dis[u]+edge[u][k];
num[k]=edge[u][k];
}else if(dis[u]+edge[u][k]==dis[k] && num[k]>edge[u][k]){
num[k]=edge[u][k];
}
}
}
}
}
int main(){
fill(edge[0],edge[0]+maxsize*maxsize,inf);
fill(dis,dis+maxsize,inf);
scanf("%d%d",&n,&m);
while(m--){
int from,to,cost;
scanf("%d%d%d",&from,&to,&cost);
edge[from][to]=edge[to][from] = min(edge[to][from],cost);
}
dijkstra(1);
printf("%d\n",sum);
return 0;
}
邻接表实现:
#include<bits/stdc++.h>
using namespace std;
const int maxsize=10005;
const int inf = 0x3f3f3f;
struct Edge{
int to,cost;
};
int dis[maxsize];
bool visit[maxsize];
int n,m,sum=0;
vector<Edge>edge[maxsize];
int cost[maxsize];
void dijkstra(int start){
dis[start]=0;
for(int i=0;i<n;i++){
int min=inf,u=-1;
for(int j=1;j<=n;j++){
if(min>dis[j] && visit[j]==false){
min=dis[j];
u=j;
}
}
if(min==inf) return;
visit[u]=true;
sum+=cost[u];
for(int k=0;k<edge[u].size();k++){
int to=edge[u][k].to;
if(visit[to]==false && dis[u] + edge[u][k].cost< dis[to] ){
dis[to] = dis[u] + edge[u][k].cost;
cost[to] = edge[u][k].cost;
}else if(dis[u] + edge[u][k].cost == dis[to] && cost[to]>edge[u][k].cost){
cost[to] = edge[u][k].cost;
}
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
int from,to,cost;
scanf("%d%d%d",&from,&to,&cost);
edge[from].push_back({to,cost});
edge[to].push_back({from,cost});
}
fill(dis+2,dis+n+1,inf);
dijkstra(1);
printf("%d",sum);
return 0;
}