【板子】最短路

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

 

 

更新一下kb大神的板子。

 

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e5+7;
const int inf = 0x3f3f3f3f;

struct Edge{
    int v;
    int cost;
    Edge(int _v = 0,int _cost = 0):v(_v),cost(_cost){}
};

vector<Edge> e[maxn];

void addedge(int u,int v,int w){
    e[u].push_back(Edge(v,w));
}

bool vis[maxn];
int cnt[maxn];
int dis[maxn];

int n,m,c;

bool spfa(int s){
    memset(vis,false,sizeof(vis));
    for(int i = 1; i <= n; i++) dis[i] = inf;

    vis[s] = true;
    dis[s] = 0;
    queue<int> Q;
    while(!Q.empty())   Q.pop();
    Q.push(s);
    memset(cnt,0,sizeof(cnt));
    cnt[s] = 1;

    while(!Q.empty()){
        int u = Q.front();
        Q.pop();
        vis[u] = false;
        for(int i = 0; i < e[u].size();i++){
            int v = e[u][i].v;
            if(dis[v] > dis[u] + e[u][i].cost){
                dis[v] = dis[u] + e[u][i].cost;
                if(!vis[v]){
                    vis[v] = true;
                    Q.push(v);
                    if(++cnt[v] > n)    return false;
                    //cnt[i]
                }
            }
        }
    }

    return true;
}

 

 

 

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 }

 

 kb大神的板子

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
const int inf = 0x3f3f3f3f;

struct node{
    int v;
    int c;
    node(int _v = 0,int _c = 0):v(_v),c(_c){}
    bool operator < (const node &r)const{
        return c > r.c;
    }    

};


struct Edge{
    int v,cost;
    Edge(int _v = 0, int _cost = 0):v(_v),cost(_cost){}
};

vector< Edge > e[maxn];
bool vis[maxn];
int dis[maxn];
int n,m,c;

void addedge(int u,int v,int w){
    e[u].push_back(Edge(v,w));
}

void dij(int s){
    memset(vis,false,sizeof(vis));
    for(int i = 1; i <= n ;i++) dis[i] = inf;
    priority_queue <node> Q;
 
    while(!Q.empty()) Q.pop();
    dis[s] = 0;
    Q.push(node(s,0));
    node tmp;

    while( !Q.empty() ){
      tmp = Q.top();
      Q.pop();
      int u = tmp.v;
      if(vis[u])  continue;
      vis[u] = true;
      for(int i = 0; i < e[u].size(); i++){
        int v = e[tmp.v][i].v;
        int cost = e[u][i].cost;
        if(!vis[v] && dis[v] > dis[u] + cost){
          dis[v] = dis[u] + cost;
          Q.push(node(v,dis[v]));
        }
      }
    }
}

 

posted @ 2018-05-24 14:58  甜酒果。  阅读(246)  评论(1编辑  收藏  举报