【图论】最短路

例题: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 }

有时间写具体的证明,或者补充新板子。

待更新。咕咕咕咕咕……

猜你喜欢

转载自www.cnblogs.com/Asumi/p/9082911.html