随着如今社会的不断变化,交通问题也变得越来越重要,所以市长决定建设一些公路来方便各个城市之间的贸易和交易。虽然市长的想法很好,但是他也遇到了一般人也经常头疼的问题,那就是手头的经费有限……
在规划过程中,设计师们已经预算出部分城市之间建设公路的经费需求。现在市长想知道,它能不能将他的m 个城市在有限的经费内实现公路交通。如果可以的话,输出Yes,否则输出No(两个城市不一定要直接的公路相连,间接公路到达也可以。)
测试输入包含多条测试数据。
每个测试数据的第 1 行分别给出可用的经费 c,道路数目 n,以及城市数目 m。接下来的 n 行给出建立公路的成本信息,每行给出三个整数,分别是相连的两个城市 v 1 、v 2 以及建设公路所需的成本 h。
对每个测试用例,输出 Yes 或 No。
20 10 5
1 2 6
1 3 3
1 4 4
1 5 5
2 3 7
2 4 7
2 5 8
3 4 6
3 5 9
4 5 2
Yes
10 2 2
1 2 5
1 2 15
Yes
对于100%的数据,保证 c<1000000,n<10000, m<100,0 这题的思路很明显是利用最小生成树的思想,首先通过最小生成树算法(我用的prim算法)计算出要花的经费,再与题干中的经费c对比大小,如果比c小就说明有方案Yes,否则就是No。具体实现思路在代码备注中。思路
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
Long c=scanner.nextLong();
int n=scanner.nextInt();
int m=scanner.nextInt();
int [][]city=new int[m+1][m+1];//地图数组
//初始化city,初始都是100,也就是正无穷,不可达
for(int i=0;i<m;++i){
for(int j=0;j<m;++j){
city[i][j]=100;
}
}
//根据输入设置city的初始化值
for(int i=0;i<n;++i){
//因为题干中是从1开始的,但是数组是从0开始的,所以每个都要-1
int x=scanner.nextInt()-1;
int y=scanner.nextInt()-1;
int h=scanner.nextInt();
//因为题干中说了每个城市之间有不同的路线,所以在city数组中只保存最小的路线
if(city[x][y]>h){
city[x][y]=h;
city[y][x]=h;
}
}
//vis表示哪些结点访问过
boolean []vis=new boolean[m];
//初始只有0结点访问过
for (int i=0;i<m;++i){
vis[i]=false;
}
vis[0]=true;
//利用prim最小生成树来做,寻找每次的最小权重的值,
// 为了防止寻找到的边会组成圈,所以在邻接矩阵中已访问的结点中的边寻找最小边
// 并且最小边满足列中对应的结点在vis没有访问过,而行在vis中访问过,按照这样寻找到的最小边就是不会成圈的边
for (int i=0;i<m-1;++i){
int min=101;
int node=m+1;
for (int j=0;j<m&&vis[j];++j){
for (int k=0;k<m;++k){
if(vis[k]) continue;
if(min>city[j][k]){
min=city[j][k];
node=k;
}
}
}
// 把寻找到的最小边对应的结点放进vis中
vis[node]=true;
// 没找到一个最小边就去减经费c,如果最后c大于零说明有方案,否则就没有方案
c-=min;
}
if(c>=0) System.out.println("Yes");
else System.out.println("No");
}
}