SCOJ4427 / TOPOI 4404: Miss Zhao's Graph 題解
阿新 • • 發佈:2019-03-24
處理 logs its boa max 最大 長度 bool rap Input Sample 2
具體做法
題目鏈接
SCOJ
TOPOI
題目描述
Problem
給定一個包含n個頂點m條邊的帶權有向圖,找一條邊數最多的路徑,且路徑上的邊的權值嚴格遞增。
圖中可能有重邊和自環。
Input Data
第一行,兩個整數n和m,表示頂點數和邊數。
接下來m行,每行三個整數u,v,w,表示頂點u到頂點v有一條權值為w的邊。
Output Data
一行,一個整數。
Input Sample 1
3 3
1 2 1
2 3 2
3 1 3
Output Sample 1
3
Input Sample 2
6 7
1 2 1
3 2 5
2 4 2
2 5 2
2 6 9
5 4 3
4 3 4
Input Sample 2
6
Data Limit
題目思路
由於我太弱了,想不出更好的做法 ,更快更強的做法請看 大佬的題解(這個可以點)
可能會有長度相同的邊而又要滿足嚴格遞增是這道題中的問題所在
蒟蒻的思路很簡單,用vector存以每一個節點結尾的路徑信息 (數組會MLE)
信息1:這個點是由哪條邊過來的
信息2:由這條邊過來的路徑最大長度是多少
具體做法
先對每條邊按長度排序,保證長度不下降
第一條邊單獨做,直接將信息存入vector
sort (a + 1, a + m + 1, cmp); //將邊按從大到小排序 v[a[1].v].push_back((q){1, 1}); //第一條邊單獨處理
然後枚舉每一條邊,枚舉每個u的方案,更新方案和答案
代碼
(代碼不長,但是挺慢,空間也大,大佬的強多了)
#include <bits/stdc++.h> using namespace std; const int maxn = 300008; int n, m, ans = 1; struct e{ int u, v, w; }a[maxn]; //e記錄每一條邊信息 struct q{ int num, k; //num表示路徑長度(邊數),k表示由第k條邊走來 }; //q存儲到每個節點方案的信息 bool cmp (e a, e b) { return a.w < b.w; } vector <q> v[maxn]; int main(){ scanf ("%d %d", &n, &m); for (int i = 1; i <= m; i++) scanf ("%d %d %d", &a[i].u, &a[i].v, &a[i].w); sort (a + 1, a + m + 1, cmp); //將邊按從大到小排序 v[a[1].v].push_back((q){1, 1}); //第一條邊單獨處理 for (int i = 2; i <= m; i++){ v[a[i].v].push_back((q){1, i}); //先存入vector中 int t = a[i].u, len = v[a[i].v].size(); //記錄當前的長度(下標) for (int j = 0; j < v[t].size(); j++){ //枚舉u的方案 if (a[v[t][j].k].w < a[i].w) { v[a[i].v][len-1].num = max (v[a[i].v][len-1].num, v[t][j].num + 1); ans = max (ans, v[a[i].v][len-1].num); //如果滿足嚴格遞增更新方案和答案 } } } printf ("%d", ans); return 0; }
SCOJ4427 / TOPOI 4404: Miss Zhao's Graph 題解