例题:hdu的1874
FLOYD
a->b有两种走法,1、a->k->b,2、a->b
这是主要思想。那每次保留最短路径即可。
dp[i][j] = min(dp[i][j] , dp[i][k] + dp[k][j])
1 #include<iostream> 2 #include<vector> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 const int maxn = 205; 7 8 int n,m; 9 int mp[maxn][maxn]; 10 11 void init(int n){ 12 for(int i = 0; i < n ;i++){ 13 for(int j = 0 ; j < n ;j++){ 14 if(i == j) 15 mp[i][j] = 0; 16 else 17 mp[i][j] = 1e9; 18 } 19 } 20 } 21 22 int main(){ 23 24 while(cin>>n>>m){ 25 init(n); 26 int x,y,z; 27 28 for(int i = 1; i <= m ;i++){ 29 cin>>x>>y>>z; 30 mp[x][y] = min(z,mp[x][y]); 31 mp[y][x] = min(z,mp[y][x]); 32 } 33 34 int s,t; 35 cin>>s>>t; 36 37 for(int k = 0; k < n ;k++){ 38 for(int i = 0; i < n ;i++){ 39 for(int j = 0; j < n ;j++){ 40 mp[i][j] = min(mp[i][j],mp[i][k] + mp[k][j]); 41 //cout<<mp[i][j]<<endl; 42 } 43 } 44 } 45 //cout<<mp[1][2]<<endl; 46 if(mp[s][t] == 1e9) 47 cout<<-1<<endl; 48 else 49 cout<<mp[s][t]<<endl; 50 } 51 52 return 0; 53 }
SPFA
基于dp的思想。十分有趣的板子
e[] 存边
d[] 存距离
inq[] 判断是否在queue里。
主要的dp思想就是
dp[v] = max(dp[now] + e[now][i].second , dp[v])
1 #include<iostream> 2 #include<stack> 3 #include<vector> 4 #include<queue> 5 #include<algorithm> 6 using namespace std; 7 const int maxn = 2e5+7; 8 9 vector< pair<int,int> > e[maxn]; 10 11 int n,m; 12 int d[maxn],inq[maxn]; 13 14 void init(){ 15 for(int i = 0; i < maxn; i++) 16 e[i].clear(); 17 for(int i = 0 ;i < maxn ; i++) 18 inq[i] = 0; 19 for(int i = 0 ; i < maxn ; i++) 20 d[i] = 1e9; 21 } 22 23 int main(int argc, const char * argv[]) { 24 while(cin>>n>>m){ 25 init(); 26 int x,y,z; 27 for(int i = 0; i < m ;i++){ 28 cin>>x>>y>>z; 29 e[x].push_back(make_pair(y,z)); 30 e[y].push_back(make_pair(x,z)); 31 } 32 int s,t; 33 cin>>s>>t; 34 queue<int>Q; 35 Q.push(s);d[s] = 0 ;inq[s] = 1; 36 while( !Q.empty() ){ 37 int now = Q.front(); 38 Q.pop(); 39 inq[now] = 0; 40 for(int i = 0; i < e[now].size() ; i++){ 41 int v = e[now][i].first; 42 if(d[v] > d[now] + e[now][i].second){ 43 d[v] = d[now] + e[now][i].second; 44 if(inq[v] == 1) 45 continue; 46 inq[v] = 1; 47 Q.push(v); 48 } 49 } 50 51 } 52 if(d[t] == 1e9) 53 cout<<-1<<endl; 54 else{ 55 cout<<d[t]<<endl; 56 } 57 } 58 return 0; 59 }
DIJSTRA
其实就是在spfa上做了优先队列的改进,省略了inq[]数组。
第一次用这个优先队列,感觉很妙。
1 #include<iostream> 2 #include<stack> 3 #include<vector> 4 #include<queue> 5 #include<algorithm> 6 using namespace std; 7 const int maxn = 2e5+7; 8 9 vector< pair<int,int> > e[maxn]; 10 11 int n,m; 12 int d[maxn]; 13 14 void init(){ 15 for(int i = 0; i < maxn; i++) 16 e[i].clear(); 17 for(int i = 0 ; i < maxn ; i++) 18 d[i] = 1e9; 19 } 20 21 int main(int argc, const char * argv[]) { 22 while(cin>>n>>m){ 23 init(); 24 int x,y,z; 25 for(int i = 0; i < m ;i++){ 26 cin>>x>>y>>z; 27 e[x].push_back(make_pair(y,z)); 28 e[y].push_back(make_pair(x,z)); 29 } 30 int s,t; 31 cin>>s>>t; 32 priority_queue <pair<int,int> >Q; 33 d[s] = 0; 34 Q.push( make_pair(-d[s],s) ); 35 while( !Q.empty() ){ 36 int now = Q.top().second; 37 Q.pop(); 38 39 for(int i = 0; i < e[now].size() ; i++){ 40 int v = e[now][i].first; 41 if(d[v] > d[now] + e[now][i].second){ 42 d[v] = d[now] + e[now][i].second; 43 Q.push( make_pair(-d[v],v)); 44 } 45 } 46 47 } 48 if(d[t] == 1e9) 49 cout<<-1<<endl; 50 else{ 51 cout<<d[t]<<endl; 52 } 53 } 54 return 0; 55 }
有时间写具体的证明,或者补充新板子。
待更新。咕咕咕咕咕……