Time Limit: 1000MS | Memory Limit: 65536K | |
---|---|---|
Total Submissions: 43861 | Accepted: 14902 |
Bessie is out in the field and wants to get back to the barn to get as much sleep as possible before Farmer John wakes her for the morning milking. Bessie needs her beauty sleep, so she wants to get back as quickly as possible.ios
Farmer John's field has N (2 <= N <= 1000) landmarks in it, uniquely numbered 1..N. Landmark 1 is the barn; the apple tree grove in which Bessie stands all day is landmark N. Cows travel in the field using T (1 <= T <= 2000) bidirectional cow-trails of various lengths between the landmarks. Bessie is not confident of her navigation ability, so she always stays on a trail from its start to its end once she starts it.算法
Given the trails between the landmarks, determine the minimum distance Bessie must walk to get back to the barn. It is guaranteed that some such route exists.數組
* Line 1: Two integers: T and Napp
* Lines 2..T+1: Each line describes a trail as three space-separated integers. The first two integers are the landmarks between which the trail travels. The third integer is the length of the trail, range 1..100.ide
* Line 1: A single integer, the minimum distance that Bessie must travel to get from landmark N to landmark 1.學習
5 5 1 2 20 2 3 30 3 4 20 4 5 20 1 5 100
90
INPUT DETAILS:優化
There are five landmarks.ui
OUTPUT DETAILS:spa
Bessie can get home by following trails 4, 3, 2, and 1.code
思路:
經典最短路徑板子題(模板題)
如今用 Dijkstra算法, spfa(bellman ford)算法, Floyd算法, 深搜DFS都寫一遍回顧下
使用快讀(代碼未寫出)之後仍T,說明DFS作了不少無用的搜索,在優化搜索的程度上能夠進階學習A*搜索算法
#include<iostream> #include<cstring> #include<algorithm> using namespace std; #define ms(a,b) memset(a,b,sizeof(b)); const int inf = 0x3f3f3f3f; const int N = 1000 + 10; int map[N][N]; bool book[N]; int minn , n; void dfs(int index,int step) { if (index == 1) { minn = min(minn, step); return; } if (step > minn)return; for (int i = 1; i <= n; ++i) { if (!book[i] && map[index][i] != inf) { book[i] = 1; dfs(i, step + map[index][i]); book[i] = 0; } } } int main() { ios::sync_with_stdio(false); cin.tie(0); int t, t1, t2, w; while (cin >> t >> n) { minn = inf; ms(map,inf); ms(book,false); //memset(map, inf, sizeof(map)); //memset(book, false, sizeof(book)); while (t--) { cin >> t1 >> t2 >> w; map[t1][t2] = map[t2][t1] = min(map[t1][t2], w); } book[n] = 1; dfs(n, 0); cout << minn << endl; } return 0; }
#include <stdio.h> #include <string.h> #include <string> #include <iostream> #include <stack> #include <queue> #include <vector> #include <algorithm> #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; const int inf=1<<29; int map[1010][1010];//map[i][j]表示從i-->j的距離 int dist[1010];//dist[i]從v1到i的距離 int vis[1010];//標記有沒有被訪問過 void dijkstra(int n) { int k,min; for(int i=1; i<=n; i++) { dist[i]=map[1][i]; vis[i]=0; } for(int i=1; i<=n; i++)//遍歷頂點 { k=0; min=inf; for(int j=1; j<=n; j++) if(vis[j]==0&&dist[j]<min) { min=dist[j]; k=j; } vis[k]=1; for(int j=1; j<=n; j++) if(vis[j]==0&&dist[k]+map[k][j]<dist[j]) dist[j]=dist[k]+map[k][j];//若是找到了通路就加上 } return; } int main() { int t,n,a,b,w; while(~scanf("%d%d",&t,&n)) { mem(map,0); mem(vis,0); mem(dist,0); for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) map[i][j]=inf;//初始化爲無窮大 for(int i=1; i<=t; i++) { scanf("%d%d%d",&a,&b,&w); if(w<map[a][b]) { map[a][b]=w; map[b][a]=map[a][b];//創建無向圖 }//這裏是判斷是否有重邊,應爲兩點之間的路,未必只有一條。 } dijkstra(n); printf("%d\n",dist[n]); } return 0; }
#include<cstring> #include <iostream> #include <algorithm> #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; const int inf = 1 << 29; int map[1010][1010];//map[i][j]表示從i-->j的距離 int main() { int t, n, a, b, w; while (~scanf("%d%d", &t, &n)) { mem(map, 0); //初始化 for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (i == j) map[i][j] = 0; else map[i][j] = inf;//初始化爲無窮大 //創建圖 for (int i = 1; i <= t; i++){ scanf("%d%d%d", &a, &b, &w); map[a][b] = map[b][a] = min(w, map[a][b]);//創建無向圖 }//這裏是判斷是否有重邊,應爲兩點之間的路,未必只有一條。 //弗洛伊德(Floyd)核心語句 for (int k = 1; k <= n; k++) for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (map[i][k] + map[k][j] < map[i][j]) map[i][j] = map[i][k] + map[k][j]; printf("%d\n", map[1][n]); } return 0; }
#include <iostream> #include <vector> #include <algorithm> #include <cstdio> typedef long long ll; //typedef unsigned long long ull; using namespace std; const int N = 1005, T = 4005; int n, t; int dis[N]; vector<vector<int> > gra(T, vector<int> (3)); //鄰接表存儲圖 const int inf = 1 << 29; void bellmanford() { for (int i = 1; i <= n; ++i) { dis[i] = inf; } dis[1] = 0; for (int i = 1; i < n; ++i) { for (int j = 1; j <= t * 2; ++j) { dis[gra[j][1]] = min(dis[gra[j][1]], dis[gra[j][0]] + gra[j][2]); } } } int main() { scanf("%d%d", &t, &n); for (int i = 0, index = 1; i < t; ++i) { int a, b, c; scanf("%d%d%d", &a, &b, &c); gra[index][0] = a, gra[index][1] = b, gra[index][2] = c; ++index; gra[index][1] = a, gra[index][0] = b, gra[index][2] = c; ++index; } bellmanford(); printf("%d\n", dis[n]); return 0; }
//spfa #include <vector> #include <algorithm> #include <cstdio> #include <queue> using namespace std; const int N = 1005, T = 4005; int n, t; int dis[N], vis[N]; //dis數組存單元源點到其餘各個點的距離 //vis存頂點v是否已經在隊列當中以減小沒必要要的操做 vector<int> to[N], edge[N]; //鄰接表分別存以i爲下標的鄰接的頂點和權值 const int inf = 1 << 29; void spfa() { queue<int> q; for (int i = 1; i <= n; ++i) { dis[i] = inf; } dis[1] = 0; q.push(1); while (!q.empty()) { int u = q.front(); q.pop(); vis[u] = false; for (int i = 0; i < to[u].size(); ++i) { //遍歷鄰接的頂點 int v = to[u][i], w = edge[u][i]; if (dis[v] > dis[u] + w) { dis[v] = dis[u] + w; if (!vis[v]) { vis[v] = true; q.push(v); } } } } } int main() { scanf("%d%d", &t, &n); for (int i = 0; i < t; ++i) { int a, b, c; scanf("%d%d%d", &a, &b, &c); //無向圖 to[a].push_back(b); edge[a].push_back(c); to[b].push_back(a); edge[b].push_back(c); } spfa(); printf("%d\n", dis[n]); return 0; }
寫完幾種模板之後分析一下時間複雜度