隨想錄 Day 72 拓撲排序、最短路徑 樸素dijkstra
117. 軟件構建
117. 軟件構建
時間限制:1.000S 空間限制:256MB
題目描述
某個大型軟件項目的構建系統擁有 N 個文件,文件編號從 0 到 N - 1,在這些文件中,某些文件依賴于其他文件的內容,這意味著如果文件 A 依賴于文件 B,則必須在處理文件 A 之前處理文件 B (0 <= A, B <= N - 1)。請編寫一個算法,用于確定文件處理的順序。
輸入描述
第一行輸入兩個正整數 N, M。表示 N 個文件之間擁有 M 條依賴關系。
后續 M 行,每行兩個正整數 S 和 T,表示 T 文件依賴于 S 文件。
輸出描述
輸出共一行,如果能處理成功,則輸出文件順序,用空格隔開。
如果不能成功處理(相互依賴),則輸出 -1。
輸入示例
5 4
0 1
0 2
1 3
2 4
輸出示例
0 1 2 3 4
提交:這里沒必要像題解一樣用umap
接下來我給出 拓撲排序的過程,其實就兩步:
找到入度為0 的節點,加入結果集
將該節點從圖中移除
# include <iostream>
# include <vector>
# include <queue>
using namespace std;
int n , m;
int main() {cin>> n >> m;vector<int> inCnt(n , 0);vector<vector<int> > edges(n);for (int i = 0; i < m; i++) {int start, end;cin >> start >> end;edges[start].push_back(end);inCnt[end]++;}// for (int i = 0; i < n; i++) {// cout << inCnt[i]<<" ";// }//cout << endl;//int cnt = 0;queue<int> out;for (int i = 0; i < n; i++) {if (inCnt[i] == 0) {out.push(i);}}vector<int> res;while(out.size() != 0 ) {int now = out.front();out.pop();res.push_back(now);for (int j : edges[now]) {inCnt[j]--;if (inCnt[j] == 0) out.push(j);}}///注意這里輸出格式if (res.size() == n) {for (int i = 0; i < n; i++) {if (i == n-1) cout << res[i];else cout<< res[i] << " ";}} else cout << -1;
}
47. 參加科學大會
7. 參加科學大會(第六期模擬筆試)
時間限制:1.500S 空間限制:128MB
題目描述
小明是一位科學家,他需要參加一場重要的國際科學大會,以展示自己的最新研究成果。
小明的起點是第一個車站,終點是最后一個車站。然而,途中的各個車站之間的道路狀況、交通擁堵程度以及可能的自然因素(如天氣變化)等不同,這些因素都會影響每條路徑的通行時間。
小明希望能選擇一條花費時間最少的路線,以確保他能夠盡快到達目的地。
輸入描述
第一行包含兩個正整數,第一個正整數 N 表示一共有 N 個公共汽車站,第二個正整數 M 表示有 M 條公路。
接下來為 M 行,每行包括三個整數,S、E 和 V,代表了從 S 車站可以單向直達 E 車站,并且需要花費 V 單位的時間。
輸出描述
輸出一個整數,代表小明從起點到終點所花費的最小時間。
輸入示例
7 9
1 2 1
1 3 4
2 3 2
2 4 5
3 4 2
4 5 3
2 6 4
5 7 4
6 7 9
輸出示例
12
提交
為了防止intmax越界,這里用了intmax/2,作比較
# include <iostream>
# include <vector>
# include <climits>
using namespace std;
int n, m;int main() {cin>> n >> m;vector<vector<int> > map(n + 1, vector<int>(n + 1, INT_MAX/2));for (int i = 0; i < m ; i++) {int start, end, weight;cin>> start>> end >> weight;//cout << start << end << weight << endl;map[start][end] = weight;}vector <bool> visited(n + 1, false);vector <int> minDis(n+1, INT_MAX/2);visited[0] = true;minDis[0] = 0;minDis[1] = 0;visited[1] = true;int now = 1;int res = 0;for (int t = 0; t < n-1; t++) {//update minDisint minD = INT_MAX/2, inIndex = -1;for (int i = 1; i <= n; i++) {if (visited[i] == false) {//cout << i << "original " << minDis[i] << endl;minDis[i] = min(minDis[i], minDis[now] + map[now][i]);if (minDis[i] < minD) {minD = minDis[i];inIndex = i;}//cout << i << "changed " << minDis[i] << endl;}}//find target point and visited = trueif (minD == INT_MAX/2) break;//cout << inIndex << "chosen one " << minDis[inIndex] << endl;visited[inIndex] = true;now = inIndex;//res = minD;}if(visited[n] == true){cout << minDis[n];}else {cout << -1;}//cout << res;
}
優化一下不會intmax越界,多加一個有沒有邊的判斷(很自然)
# include <iostream>
# include <vector>
# include <climits>
using namespace std;
int n, m;int main() {cin>> n >> m;vector<vector<int> > map(n + 1, vector<int>(n + 1, INT_MAX));for (int i = 0; i < m ; i++) {int start, end, weight;cin>> start>> end >> weight;//cout << start << end << weight << endl;map[start][end] = weight;}vector <bool> visited(n + 1, false);vector <int> minDis(n+1, INT_MAX);visited[0] = true;minDis[0] = 0;minDis[1] = 0;visited[1] = true;int now = 1;int res = 0;for (int t = 0; t < n-1; t++) {//update minDisint minD = INT_MAX, inIndex = -1;for (int i = 1; i <= n; i++) {if (visited[i] == false) {//cout << i << "original " << minDis[i] << endl;if (map[now][i] != INT_MAX) {minDis[i] = min(minDis[i], minDis[now] + map[now][i]);}if (minDis[i] < minD) {minD = minDis[i];inIndex = i;}//cout << i << "changed " << minDis[i] << endl;}}//find target point and visited = trueif (minD == INT_MAX) break;//cout << inIndex << "chosen one " << minDis[inIndex] << endl;visited[inIndex] = true;now = inIndex;//res = minD;}if(visited[n] == true){cout << minDis[n];}else {cout << -1;}//cout << res;
}