输入包含多组数据,每组数据第一行包含两个正整数m(1≤m≤500)和n(1≤n≤30),其中n表示有n个收费站,编号依次为1、2、…、n。出发地的编号为0,终点的编号为n,即需要从0到n。
紧接着m行,每行包含三个整数f、t、c,(0≤f, t≤n; 1≤c≤10),分别表示从编号为f的地方开到t,需要交c元的过路费。
对应每组数据,请输出至少需要交多少过路费。
8 4 0 1 10 0 2 5 1 2 2 1 3 1 2 1 3 2 3 9 2 4 2 3 4 4
7
单源最短路径,dijkstra算法。 #include<iostream> #include<vector> #include<string> #include<algorithm> #include<functional> #include <map> #include <set> #include <unordered_set> #include <unordered_map> #include <exception> #include <iomanip> #include <memory> #include <sstream> #include <list> using namespace std; #define INF 10000 int main(int argc, char** argv) { //freopen("in.txt", "r", stdin); int m,n; while (cin >> m >> n) { vector<vector<int>> cost(n + 1, vector<int>(n + 1, INF)); int f, t, c; for (int i = 0; i < m; ++i) { cin >> f >> t >> c; cost[f][t] = c; } vector<int> minDis(n + 1, INF); vector<bool> visited(n + 1, false); minDis[0] = 0; while (true) { int next = -1; for (int i = 0; i <= n; ++i) { if (!visited[i] && (next == -1 || minDis[i] < minDis[next])) next = i; } if (next == -1) break; visited[next] = true; for (int i = 0; i <= n; ++i) minDis[i] = min(minDis[i], minDis[next] + cost[next][i]); } cout << minDis[n] << endl; } return 0; }
package test; import java.util.Scanner; public class TarStation { public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNext()) { int m = in.nextInt(); int n = in.nextInt(); // 最短路径 int dist[] = new int[n + 1]; // 前一个顶点号 int path[] = new int[n + 1]; // 顶点是否被确定了 boolean S[] = new boolean[n + 1]; // 初始化邻接矩阵 int[][] Edge = new int[n + 1][n + 1]; for (int i = 0; i < n + 1; i++) { for (int j = 0; j < n + 1; j++) { Edge[i][j] = Integer.MAX_VALUE; } } // 输入邻接矩阵 for (int i = 0; i < m; i++) { Edge[in.nextInt()][in.nextInt()] = in.nextInt(); } Dijkstr(Edge, dist, path, S, m, n); } } private static void Dijkstr(int[][] edge, int[] dist, int[] path, boolean[] s, int m, int n) { for (int i = 0; i < n + 1; i++) { dist[i] = edge[0][i]; if (i != 0 && dist[i] < Integer.MAX_VALUE) path[i] = 0; else path[i] = -1; } // 开始对对一个站进行操作 s[0] = true; dist[0] = 0; // 从顶点v确定n条路径 for (int i = 0; i < n; i++) { int min = Integer.MAX_VALUE, u = 0; // 选择当前不在S中具有最短路径的顶点u for (int j = 0; j < n + 1; j++) { if (!s[j] && dist[j] < min) { u = j; min = dist[j]; } } // 表示u已经在最短路径上 s[u] = true; for (int k = 0; k < n + 1; k++) { if (!s[k] && edge[u][k] < Integer.MAX_VALUE && dist[u] + edge[u][k] < dist[k]) { dist[k] = dist[u] + edge[u][k]; path[k] = u; } } } System.out.println(dist[n] + ""); } }
#include <cstdio> #include <algorithm> using namespace std; int main() { int stations[31][31]; int m,n,f,t,c; const int INF = 0x7fffffff; while(scanf("%d%d",&m,&n) != EOF){ for(int i = 0; i <= n; i++){ for(int j = 0; j <= n; j++) stations[i][j] = INF; } for(int i = 0; i < m; i++){ scanf("%d%d%d",&f,&t,&c); stations[f][t] = c; } for(int k = 1; k <= n; k++){ for(int i = 0; i <= n; i++){ for(int j = 0; j <= n; j++){ if(k != i && k != j && i != j && stations[i][k] != INF && stations[k][j] != INF){ stations[i][j] = min(stations[i][j],stations[i][k]+stations[k][j]); } } } } printf("%d\n",stations[0][n]); } return 0; }
#include<iostream> #include<vector> #include<map> using namespace std; int main() { int m,n; int a,b,c; while(cin>>m>>n) { vector<vector<int> > mp(n+1,vector<int>(n+1)); for(int i=0; i<n+1; i++) {//初始化所有距离 for(int j=0; j<n+1; j++) { if(i==j) mp[i][j]=0; else mp[i][j]=1<<12; } } while(m-->0) { cin>>a>>b>>c; mp[a][b]=c;//接受输入 } vector<int> dis(mp[0]);//结点0到其他点的距离 vector<bool> sp(n+1,false);//标记最短路径点集 for(int i=0;i<n+1;i++){ int MIN=1<<12; int u; for(int j=0;j<n+1;j++){//扩展新的结点,即满足,到该节点的路径是剩余结点中最短的 if(!sp[j]&&dis[j]<MIN){ u=j; MIN=dis[j]; } } sp[u]=true; for(int k=0;k<n+1;k++){ dis[k]=min(dis[k],dis[u]+mp[u][k]); } } cout<<dis[n]<<endl; } return 0; }
package com.yzh.hehe;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
//用题目上的提供的输入数据测试没有问题,但在用scanner 接收输入时会出格式上的错误(Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException),哪位大神指点指点
public class LeatestCarFee {
public static void main(String[] args) {
String string="8 4";
int m =Integer.valueOf(string.split("\\s+")[0]);
int n =Integer.valueOf(string.split("\\s+")[1]);
List<FeeLine>[] arr = new List[n];
for (int i = 0; i < arr.length; i++) {
arr[i]=new ArrayList<FeeLine>();
}
String[] tempArr={"0 1 10",
"0 2 5",
"1 2 2",
"1 3 1",
"2 1 3",
"2 3 9",
"2 4 2",
"3 4 4"};
for (int i = 0; i < m; i++) {
string=tempArr[i];
String[] sArr = string.split("\\s+");
makeGraph(arr, sArr);
}
System.out.println(leatestCarFee(arr));
//以int类型接收输入格式错误(Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException)
// Scanner scanner=new Scanner(System.in);
// while (scanner.hasNext()) {
// int m =scanner.nextInt();
// int n =scanner.nextInt();
// List<FeeLine>[] arr = new List[n];
// for (int i = 0; i < arr.length; i++) {
// arr[i]=new ArrayList<FeeLine>();
// }
// for (int i = 0; i < m; i++) {
// String[] sArr = new String[3];
// sArr[0]=String.valueOf(scanner.nextInt());
// sArr[1]=String.valueOf(scanner.nextInt());
// sArr[2]=String.valueOf(scanner.nextInt());
//
// makeGraph(arr, sArr);
// }
// System.out.println(leatestCarFee(arr));
// }
// scanner.close();
//以字符串接收输入格式错误(Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException)
// Scanner scanner=new Scanner(System.in);
// while (scanner.hasNext()) {
// String string=scanner.nextLine();
// int m =Integer.valueOf(string.split("\\s+")[0]);
// int n =Integer.valueOf(string.split("\\s+")[1]);
// List<FeeLine>[] arr = new List[n];
// for (int i = 0; i < arr.length; i++) {
// arr[i]=new ArrayList<FeeLine>();
// }
// for (int i = 0; i < m; i++) {
// string=scanner.nextLine();
// String[] sArr = string.split("\\s+");
// makeGraph(arr, sArr);
// }
// System.out.println(leatestCarFee(arr));
// }
// scanner.close();
}
private static int leatestCarFee(List<FeeLine>[] arr) {
int[] costArr = new int[arr.length+1];//记录起点到各点的最小值
//索引0位置的值设为0(初始值)
for (int i = 1; i < costArr.length; i++) {
costArr[i]=Integer.MAX_VALUE;
}
int[] findArr=new int[arr.length+1];//是否被找到值得点
int aim = 0;
while (aim!=arr.length) {
findArr[aim]=1;
aim=getLeatest(costArr, aim, arr,findArr);
}
return costArr[aim];
}
//首先找到离起点值最小(v)的点(m),点m与起点的最小值即为v,再把v与点m的邻接点(n...)的值相加和起点到这些点(n...)的值作比较更新
//重复以上步骤找出所求点到起点的最小值
private static int getLeatest(int[] costArr, int point, List<FeeLine>[] arr,int[] findArr) {
int size=arr[point].size();
int pFee=costArr[point];
for (int i = 0; i < size; i++) {
FeeLine feeLine=arr[point].get(i);
if (feeLine.fee+pFee<costArr[feeLine.point]) {
costArr[feeLine.point]=feeLine.fee+pFee;
}
}
FeeLine rec=new FeeLine(Integer.MAX_VALUE, Integer.MAX_VALUE);
for (int i = 1; i < costArr.length; i++) {
if (costArr[i]<rec.fee&&findArr[i]!=1) {
rec.fee=costArr[i];
rec.point=i;
}
}
return rec.point;
}
private static void makeGraph(List<FeeLine>[] arr,String[] sArr ) {
FeeLine feeLine=new FeeLine(Integer.valueOf(sArr[1]), Integer.valueOf(sArr[2]));
arr[Integer.valueOf(sArr[0])].add(feeLine);
}
}
class FeeLine {
int point;
int fee;
FeeLine(int point,int fee){
this.point=point;
this.fee=fee;
}
}
//回溯法 #include<iostream> using namespace std; #define Max 1024 int edge[Max][Max]; int VerNum; int EdgeNum; int Current[Max]; int Bestcost; int Currentcost; void swap(int& a, int& b){ int temp; temp = a; a = b; b = temp; } void Function(int m) { for(int i = m; i<VerNum+1; i++){ swap(Current[m],Current[i]); if(edge[Current[m-1]][Current[m]]+Currentcost < Bestcost && edge[Current[m-1]][Current[m]]!=0) { if(Current[m]==VerNum){ Bestcost = edge[Current[m-1]][Current[m]]+Currentcost; } else{ Currentcost += edge[Current[m-1]][Current[m]]; Function(m+1); Currentcost -= edge[Current[m-1]][Current[m]]; } } swap(Current[m],Current[i]); } } int main(){ int Num =0; while(Num < 24) { Num++; Bestcost = 10000; Currentcost = 0; cin>>EdgeNum>>VerNum; for(int i=0; i<VerNum+1; i++) { for(int j=0; j<VerNum+1; j++) { edge[i][j]=0; } } int m,n; for(int i=0; i<EdgeNum; i++) { int start,end,value; cin >> start >> end >> value; for(m=0;m!=start;m++); for(n=0;n!=end;n++); edge[m][n]=value; } for(int i=0; i<VerNum+1; i++){ Current[i] = i; } if(VerNum > 1){ Function(1); } else if(VerNum == 1){ Bestcost = edge[0][1]; } cout << Bestcost << endl; } }
import java.util.Scanner; public class Main { private static final int MAX = 99999; public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { int m = sc.nextInt(); int n = sc.nextInt(); int[][] data = new int[n+1][n+1]; for (int i = 0; i < n + 1; i++) { for (int j = 0; j < n + 1; j++) { data[i][j] = MAX; } } for (int i = 0; i < m; i++) { int f = sc.nextInt(); int t = sc.nextInt(); int b = sc.nextInt(); data[f][t] = b; } System.out.println(dija(data)); } } public static int dija(int[][] map) { int n = map.length; // s中存放的是已经求得最短路径的点 boolean[] s = new boolean[n]; // 存放着源点到所有其他点的最短路径 int[] d = new int[n]; //int[] path = new int[n]; for (int i = 0; i < n; i++) { s[i] = false; d[i] = map[0][i]; } s[0] = true; d[0] = 0; for (int i = 1; i < n; i++) { int k = choose(d, s); s[k] = true; for (int w = 0; w < n; w++) { if (!s[w] && d[k] + map[k][w] < d[w]) { d[w] = d[k] + map[k][w]; //path[w] = k; } } } return d[n-1]; } public static int choose(int[] d, boolean[] s) { int n = d.length; int min = MAX; int minPos = -1; for (int i = 0; i < n; i++) { if (d[i] < min && !s[i]) { min = d[i]; minPos = i; } } return minPos; } }
#include <iostream> #include <fstream> #include <climits> #include <algorithm> #include <vector> using namespace std; int dijkstra(vector<vector<unsigned int> > & map) { int n = map.size() - 1; vector<unsigned int> dist(map[0]); vector<int> final(n + 1, 0); //开始主循环 每次求得0到某个顶点select的最短路径 并加select到集合S中 for (int i = 1; i <= n; ++i) { int select; int min = INT_MAX; for (int j = 0; j <= n; ++j) { if (!final[j]) //如果j顶点在V-S中 { //选出当前V-S中与S有关联边 且权值最小的顶点 if (dist[j] < min) { select = j; min = dist[j]; } } } final[select] = 1; //选出该点后加入到合集S中 for (int j = 0; j <= n; ++j) //更新当前最短路径和距离 if (!final[j] && (min + map[select][j]<dist[j])) dist[j] = min + map[select][j]; } return dist[n]; } int main() { int m, n; while (cin >> m >> n) { vector<vector<unsigned int> > map(n + 1, vector<unsigned int>(n + 1)); for (int i = 0; i <= n; i++) { for (int j = 0; j <= n; j++) { if (i == j) map[i][j] = 0; else map[i][j] = INT_MAX; } } for (int i = 0; i < m; ++i) { int a, b, c; cin >> a >> b >> c; map[a][b] = c; } cout << dijkstra(map) << endl; } return 0; }
// write your code here cpp #include<stdio.h> #include<string.h> #include<stdbool.h> #define min(a,b) ( ((a)>(b)) ? (b):(a) ) int weight[31], data[31][31]; bool undone[31]; int main() { int m, n, f, t, c; while(~scanf("%d%d", &m, &n)){ //initial memset(weight+1, 0x7f, sizeof(int)*30); memset(undone, true, sizeof(undone)); memset(data, 0, sizeof(data)); while(m--){ scanf("%d%d%d", &f, &t, &c); data[f][t] = c; } //dijkstra int new_done = 0, least = -1; while(undone[n]){ //update node linked with new_done //found least of all undone for(int i=1; i<=n; ++i){ if(undone[i]){ if(least == -1) least = i; if(data[new_done][i]) weight[i] = min(weight[i], weight[new_done]+data[new_done][i]); if(weight[least] > weight[i]) least = i; } } undone[least] = false; new_done = least; least = -1; } printf("%d\n", weight[n]); } return 0; }