zoukankan      html  css  js  c++  java
  • 算法笔记--最短路算法

    1.单源最短路问题

    ①Bellman-ford算法:

    const int N=1e3+5; 
    const int INF=0x3f3f3f3f;
    struct edge{
        int u,v,cost;
    };
    int d[N];
    int V;
    vector<edge>e;
    void Bellman_ford(int s)
    {
        for(int i=0;i<V;i++)d[i]=INF;
        d[s]=0;
        while(true)
        {
            bool upd=false;
            for(int i=0;i<e.size();i++)
            {
                if(d[e[i].u]!=INF&&d[e[i].v]>d[e[i].u]+e[i].cost)
                {
                    upd=true;
                    d[e[i].v]=d[e[i].u]+e[i].cost;
                }
            }
            if(!upd)break;
        }
    }
    bool find_negative_loop()
    {
        mem(d,0);
        for(int i=0;i<V;i++)
        {
            for(int j=0;j<e.size();j++)
            {
                if(d[e[j].v]>d[e[j].u]+e[j].cost)
                {
                    d[e[j].v]=d[e[j].u]+e[j].cost;
                    if(i==V-1)return true;    
                } 
            }
        }    
        return false;
    }

    例题:poj 1860 Currency Exchange

    思路:判断是否存在正权环。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a)) 
    
    const int N=1e3+5;
    int n,m,s;
    double V;
    struct edge
    {
        int u,v;
        double r,c;
    };
    vector<edge>e;
    double d[N];
    bool Bellman()
    {
        for(int i=0;i<=n;i++)d[i]=0;
        d[s]=V;
        for(int i=1;i<=n;i++)
        {
            bool upd=false;
            for(int j=0;j<e.size();j++)
            {
                if(d[e[j].v]<(d[e[j].u]-e[j].c)*e[j].r)
                {
                    if(i==n)return true;
                    upd=true;
                    d[e[j].v]=(d[e[j].u]-e[j].c)*e[j].r;
                }
            }
            if(!upd)return false;
        }
        return false;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin>>n>>m>>s>>V;
        int u,v;
        double r,c,_r,_c;
        while(m--)
        {
            cin>>u>>v>>r>>c>>_r>>_c;
            e.pb(edge{u,v,r,c});
            e.pb(edge{v,u,_r,_c});
        }
        if(Bellman())cout<<"YES"<<endl;
        else cout<<"NO"<<endl; 
        return 0; 
    }
    View Code

    ②Dijkstra算法:

    普通版:

    const int INF=0x3f3f3f3f;
    const int N=105;
    int g[N][N];
    int d[N];
    bool vis[N];
    int n,m;
    
    void Dijkstra(int s)
    {
        mem(d,INF);
        mem(vis,false);
        d[s]=0;
        
        while(true)
        {
            int v=-1;
            for(int i=1;i<=n;i++)
            if(!vis[i]&&(v==-1||d[i]<d[v]))v=i;
            
            if(v==-1)break;
            vis[v]=true;
            
            for(int i=1;i<=n;i++)
            {
                d[i]=min(d[i],d[v]+g[v][i]);
            }
        }
    }

    例题:hdu2544最短路

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define ls rt<<1,l,m
    #define rs rt<<1|1,m+1,r
    #define pb push_back
    #define mem(a,b) memset((a),(b),sizeof(a))
    const int INF=0x3f3f3f3f;
    const int N=105;
    int g[N][N];
    int d[N];
    bool vis[N];
    int n,m;
    
    void Dijkstra(int s)
    {
        mem(d,INF);
        mem(vis,false);
        d[s]=0;
        
        while(true)
        {
            int v=-1;
            for(int i=1;i<=n;i++)
            if(!vis[i]&&(v==-1||d[i]<d[v]))v=i;
            
            if(v==-1)break;
            vis[v]=true;
            
            for(int i=1;i<=n;i++)
            {
                d[i]=min(d[i],d[v]+g[v][i]);
            }
        }
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m)&&n&&m)
        {
            mem(g,INF);
            for(int i=0;i<m;i++)
            {
                int a,b,c;
                cin>>a>>b>>c;
                g[a][b]=c;
                g[b][a]=c;
            }
            Dijkstra(1);
            printf("%d
    ",d[n]);
        }
        return 0;
    } 
    View Code

     优先队列优化版:

    const int N=1e3+5;
    const int INF=0x3f3f3f3f;
    int d[N];
    int V;
    struct edge{
        int to,cost;
    };
    vector<edge>g[N];
    void dijkstra(int s)
    {
        priority_queue<pii,vector<pii>,greater<pii> >q;
        mem(d,INF);
        d[s]=0;
        q.push(mp(0,s));
        while(!q.empty())
        {
            pii p=q.top();
            q.pop();
            int v=p.second;
            if(d[v]<p.first)continue;
            for(int i=0;i<g[v].size();i++)
            {
                edge e=g[v][i];
                if(d[e.to]>d[v]+e.cost)
                {
                    d[e.to]=d[v]+e.cost;
                    q.push(mp(d[e.to],e.to));
                }
            }
        }
    }

    例题:hdu2544最短路

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define mem(a,b) memset(a,b,sizeof(a))
    #define pii pair<int,int>
    
    const int N=1e3+5;
    const int INF=0x3f3f3f3f;
    int d[N];
    int V;
    struct edge{
        int to,cost;
    };
    vector<edge>g[N];
    void dijkstra(int s)
    {
        priority_queue<pii,vector<pii>,greater<pii> >q;
        mem(d,INF);
        d[s]=0;
        q.push(mp(0,s));
        while(!q.empty())
        {
            pii p=q.top();
            q.pop();
            int v=p.second;
            if(d[v]<p.first)continue;
            for(int i=0;i<g[v].size();i++)
            {
                edge e=g[v][i];
                if(d[e.to]>d[v]+e.cost)
                {
                    d[e.to]=d[v]+e.cost;
                    q.push(mp(d[e.to],e.to));
                }
            }
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n,m,a,b,c;
        while(cin>>n>>m)
        {
            if(n==0&&m==0)break;
            for(int i=0;i<N;i++)g[i].clear();
            for(int i=0;i<m;i++)
            {
                cin>>a>>b>>c;
                g[a].pb(edge{b,c});
                g[b].pb(edge{a,c});
            }
            dijkstra(1);
            cout<<d[n]<<endl;
        }
        return 0;
    } 
    View Code

     ③spfa算法:

    bool spfa(int s)
    {
        mem(d,INF);
        mem(c,0);
        mem(vis,false);
        d[s]=0;
        c[s]=1;
        vis[s]=true;
        queue<int>q;
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            vis[u]=false;
            for(int i=head[u];~i;i=edge[i].next)
            {
                if(d[edge[i].to]>d[u]+edge[i].w)
                {
                    d[edge[i].to]=d[u]+edge[i].w;
                    if(!vis[edge[i].to])
                    {
                        vis[edge[i].to]=true;
                        c[edge[i].to]++;
                        q.push(edge[i].to);
                        if(c[edge[i].to]>=n)
                        {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

    spfa判负环:https://blog.csdn.net/forever_dreams/article/details/81161527

    2.任意两点间的最短路问题

    ①Floyd-Warshall算法

    int d[N][N];
    int n;
    void Floyd()
    {
        for(int k=1;k<=n;k++)
        {
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
            }
        }
    }

    例题:hdu2544最短路

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define mem(a,b) memset(a,b,sizeof(a))
    #define pii pair<int,int>
    
    const int N=1e3+5;
    const int INF=0x3f3f3f3f;
    int d[N][N];
    int n;
    void Floyd()
    {
        for(int k=1;k<=n;k++)
        {
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
            }
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int m,a,b,c;
        while(cin>>n>>m)
        {
            if(n==0&&m==0)break;
            mem(d,INF);
            for(int i=1;i<=n;i++)d[i][i]=0;
            for(int i=0;i<m;i++)
            {
                cin>>a>>b>>c;
                d[a][b]=c;
                d[b][a]=c;
            }
            Floyd(); 
            cout<<d[1][n]<<endl;
        }
        return 0;
    } 
    View Code

    3.路径还原:

    const int N=1e3+5;
    const int INF=0x3f3f3f3f;
    int d[N];
    int pre[N];
    struct edge
    {
        int to,cost;
    };
    vector<edge>g[N];
    void dijkstra(int s)
    {
        mem(d,INF);
        mem(pre,-1);
        priority_queue<pii,vector<pii>,greater<pii> >q;
        d[s]=0;
        q.push(mp(0,s));
        while(!q.empty())
        {
            pii p=q.top();
            q.pop();
            int v=p.second;
            if(d[v]<p.first)continue; 
            for(int i=0;i<g[v].size();i++)
            {
                edge e=g[v][i];
                if(d[e.to]>d[v]+e.cost)
                {
                    d[e.to]=d[v]+e.cost;
                    pre[e.to]=v;
                    q.push(mp(d[e.to],e.to));
                }
            }
        }
    }
    
    vector<int> get_path(int t)
    {
        vector<int> path;
        for(;t!=-1;t=pre[t])path.pb(t);
        reverse(path.begin(),path.end());
        return path;
    }

     例题:

    POJ 2387

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long 
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=1e3+5;
    const int INF=0x3f3f3f3f;
    struct edge
    {
        int to,cost;
    };
    int d[N];
    vector<edge>g[N];
    
    void dijkstra(int s)
    {
        mem(d,INF);    
        d[s]=0;
        priority_queue<pii,vector<pii>,greater<pii> >q;
        q.push(mp(0,s));
        while(!q.empty())
        {
            pii p=q.top();
            q.pop();
            int v=p.second;
            if(d[v]<p.first)continue;
            for(int i=0;i<g[v].size();i++)
            {
                edge e=g[v][i];
                if(d[e.to]>d[v]+e.cost)
                {
                    d[e.to]=d[v]+e.cost;
                    q.push(mp(d[e.to],e.to));
                }
            }
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int t,n,a,b,c;
        while(cin>>t>>n)
        {
            for(int i=0;i<=n;i++)g[i].clear();
            while(t--)
            {
                cin>>a>>b>>c;
                g[a].pb(edge{b,c});
                g[b].pb(edge{a,c});
            }
            dijkstra(n);
            cout<<d[1]<<endl;
        }
        return 0;
    }
    View Code

    POJ 2253

    路径最大权值最小路

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<iomanip>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define pii pair<int,int>
    #define pdi pair<double,int>
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=205;
    const int INF=0x3f3f3f3f;
    struct edge
    {
        int to;
        double cost;
    };
    vector<edge>g[N];
    bool vis[N];
    double d[N];
    double x[N],y[N];
    void dijkstra(int s)
    {
        for(int i=0;i<N;i++)d[i]=INF;
        mem(vis,false);
        d[s]=0;
        priority_queue<pdi,vector<pdi>,greater<pdi> >q;
        q.push(mp(0,s));
        while(!q.empty())
        {
            pii p=q.top();
            q.pop();
            int v=p.second;
            if(vis[v])continue;
            vis[v]=true;
            for(int i=0;i<g[v].size();i++)
            {
                edge e=g[v][i];
                if(d[e.to]>max(d[v],e.cost))
                {
                    d[e.to]=max(d[v],e.cost);
                    q.push(mp(d[e.to],e.to));
                }
            }
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n;
        int cnt=0;
        while(cin>>n&&n)
        {
            for(int i=1;i<=n;i++)
            {
                g[i].clear();
                cin>>x[i]>>y[i];
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=i+1;j<=n;j++)
                {
                    double dis=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
                    g[i].pb(edge{j,dis});
                    g[j].pb(edge{i,dis});
                }
            }
            dijkstra(1);
            cout<<"Scenario #"<<++cnt<<endl;
            cout<<"Frog Distance = "<<fixed<<setprecision(3)<<d[2]<<endl;
            cout<<endl;
        }
        return 0;
    } 
    View Code

     POJ 1797

    路径流量(最小权值)最大路

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<iomanip>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define pii pair<int,int>
    #define pdi pair<double,int>
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=1e3+5;
    const int INF=0x3f3f3f3f;
    struct edge
    {
        int to,cost;
    };
    vector<edge>g[N];
    int d[N];
    bool vis[N];
    void dijkstra(int s)
    {
        mem(vis,false);
        mem(d,0);
        priority_queue<pii>q;
        vis[s]=true;
        for(int i=0;i<g[1].size();i++)
        {
            edge e=g[1][i]; 
            d[e.to]=e.cost;
            q.push(mp(e.cost,e.to));
        }
        while(!q.empty())
        {
            pii p=q.top();
            q.pop();
            int v=p.second;
            if(vis[v])continue;
            vis[v]=true;
            for(int i=0;i<g[v].size();i++)
            {
                edge e=g[v][i];
                if(d[e.to]<min(d[v],e.cost))
                {
                    d[e.to]=min(d[v],e.cost);
                    q.push(mp(d[e.to],e.to));
                }
            }
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int T,n,m,u,v,cost;
        cin>>T;
        for(int i=1;i<=T;i++)
        {
            cin>>n>>m;
            for(int i=0;i<=n;i++)g[i].clear();
            while(m--)
            {
                cin>>u>>v>>cost;
                g[u].pb(edge{v,cost});
                g[v].pb(edge{u,cost}); 
            }
            dijkstra(1);
            cout<<"Scenario #"<<i<<":"<<endl<<d[n]<<endl<<endl;
        }
        return 0;
    }
    View Code

     POJ - 3259

    判负环

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<iomanip>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define pii pair<int,int>
    #define pdi pair<double,int>
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=555;
    int d[N];
    int n;
    struct edge
    {
        int u,v,cost;
    };
    vector<edge>e;
    bool Bellman(int s)
    {
        mem(d,0);
        for(int i=1;i<=n;i++)
        {
            bool upd=false;
            for(int j=0;j<e.size();j++)
            {
                if(d[e[j].v]>d[e[j].u]+e[j].cost)
                {
                    if(i==n)return true;
                    d[e[j].v]=d[e[j].u]+e[j].cost;
                    upd=true;
                }
            }
            if(!upd)return false;
        }
        return false;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int f,u,v,t,m,w;
        cin>>f;
        while(f--)
        {
            cin>>n>>m>>w;
            e.clear();
            while(m--)
            {
                cin>>u>>v>>t;
                e.pb(edge{u,v,t});
                e.pb(edge{v,u,t});
            }
            while(w--)
            {
                cin>>u>>v>>t;
                e.pb(edge{u,v,-t});
            } 
            if(Bellman(1))cout<<"YES"<<endl;
            else cout<<"NO"<<endl;
        }
        return 0;
    }
    View Code

    POJ - 3660

    传递闭包

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define pii pair<int,int>
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=105;
    bool Mp[N][N];
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n,m,u,v;
        cin>>n>>m;
        mem(Mp,false);
        for(int i=0;i<m;i++)cin>>u>>v,Mp[u][v]=true;
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    Mp[i][j]=max(Mp[i][j],Mp[i][k]&&Mp[k][j]);
        int cnt=0;
        for(int i=1;i<=n;i++)
        {
            int t=0;
            for(int j=1;j<=n;j++)t+=Mp[i][j]+Mp[j][i];
            if(t==n-1)cnt++;
        }
        cout<<cnt<<endl;
        return 0;
    }
    View Code

     POJ - 1502

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define pii pair<int,int>
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=105;
    const int INF=0x3f3f3f3f;
    int head[N];
    ll d[N];
    int cnt;
    struct edge
    {
        int to,w,next;
    }edge[N*N];
    void add_edge(int u,int v,int w)
    {
        edge[cnt].to=v;
        edge[cnt].w=w;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    void dijkstra(int s)
    {
        mem(d,INF);
        priority_queue<pii,vector<pii>,greater<pii> >q;
        d[s]=0;
        q.push(mp(0,s));
        while(!q.empty())
        {
            pii p=q.top();
            q.pop();
            int u=p.second;
            if(d[u]<p.first)continue;
            for(int i=head[u];~i;i=edge[i].next)
            {
                if(d[edge[i].to]>d[u]+edge[i].w)
                {
                    d[edge[i].to]=d[u]+edge[i].w;
                    q.push(mp(d[edge[i].to],edge[i].to));
                }
            }
    
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n;
        string w;
        cin>>n;
        cnt=0;
        mem(head,-1);
        for(int i=2;i<=n;i++)
        {
            for(int j=1;j<i;j++)
            {
                cin>>w;
                int cost=0;
                if(w=="x")cost=INF;
                else
                {for(int i=0;i<w.size();i++)cost=cost*10+w[i]-'0';}
                add_edge(i,j,cost);
                add_edge(j,i,cost);
            }
        }
        //cout<<1<<endl;
        dijkstra(1);
        ll mx=0;
        for(int i=1;i<=n;i++)mx=max(mx,d[i]);
        cout<<mx<<endl;
        return 0;
    }
    View Code
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define pii pair<int,int>
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=105;
    const int INF=0x3f3f3f3f;
    int Mp[N][N];
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n;
        string w;
        cin>>n;
        for(int i=2;i<=n;i++)
        {
            for(int j=1;j<i;j++)
            {
                cin>>w;
                int cost=0;
                if(w=="x")cost=INF;
                else
                {for(int i=0;i<w.size();i++)cost=cost*10+w[i]-'0';}
                Mp[i][j]=cost;
                Mp[j][i]=cost;
            }
        }
        int mx=0;
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    Mp[i][j]=min(Mp[i][k]+Mp[k][j],Mp[i][j]);
        for(int i=2;i<=n;i++)mx=max(mx,Mp[1][i]);
        cout<<mx<<endl;
        return 0;
    }
    View Code

    POJ 2240

    判断是否存在正权环,bellman有点慢,好像spfa快一点

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=50;
    struct edge
    {
        int u,v;
        double w;
    };
    double d[N];
    int n;
    vector<edge>e;
    map<string,int>mp;
    bool Bellman()
    {
        for(int i=1;i<=n;i++)d[i]=0;
        d[1]=1;
        for(int i=1;i<=n;i++)
        {
            bool upd=false;
            for(int j=0;j<e.size();j++)
            {
                if(d[e[j].v]<d[e[j].u]*e[j].w)
                {
                    if(i==n)return true;
                    upd=true;
                    d[e[j].v]=d[e[j].u]*e[j].w;
                }
            }
            if(!upd)return false;
        }
        return false;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        string s,t;
        int m;
        double w;
        int cnt=0;
        while(cin>>n&&n)
        {
            mp.clear();
            e.clear();
            for(int i=1;i<=n;i++)cin>>s,mp[s]=i;
            cin>>m;
            for(int i=1;i<=m;i++)
            {
                cin>>s>>w>>t;
                e.pb(edge{mp[s],mp[t],w});
            }
            if(Bellman())cout<<"Case "<<++cnt<<": Yes"<<endl;
            else cout<<"Case "<<++cnt<<": No"<<endl;
        }
        return 0;
    }
    View Code

     POJ 1511

    又做到一题关闭同步失败的,一直TLE,哭唧唧/(ㄒoㄒ)/~~

    求每个点到1的最短路,把图反向,求1的最短路就可以了

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define pii pair<int,int>
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=1e6+5;
    const int INF=0x3f3f3f3f;
    int d[N];
    int head[N];
    int u[N],v[N],w[N];
    int cnt,p;
    struct edge
    {
        int to,w,next;
    }edge[N];
    void add_edge(int u,int v,int w)
    {
        edge[cnt].to=v;
        edge[cnt].w=w;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    void dijkstra(int s)
    {
        priority_queue<pii,vector<pii>,greater<pii> >q;
        for(int i=1;i<=p;i++)d[i]=INF;
        d[s]=0;
        q.push(mp(0,s));
        while(!q.empty())
        {
            pii p=q.top();
            q.pop();
            int u=p.second;
            if(d[u]<p.first)continue;
            for(int i=head[u];~i;i=edge[i].next)
            {
                if(d[edge[i].to]>p.first+edge[i].w)
                {
                    d[edge[i].to]=p.first+edge[i].w;
                    q.push(mp(d[edge[i].to],edge[i].to));
                }
            }
        }
    }
    int main()
    {
        int T,q;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&p,&q);
            cnt=0;
            for(int i=1;i<=p;i++)head[i]=-1;
            for(int i=1;i<=q;i++)
            {
                scanf("%d%d%d",&u[i],&v[i],&w[i]);
                add_edge(u[i],v[i],w[i]);
            }
            ll ans=0;
            dijkstra(1);
            for(int i=2;i<=p;i++)ans+=d[i];
            cnt=0;
            for(int i=1;i<=p;i++)head[i]=-1;
            for(int i=1;i<=q;i++)
            add_edge(v[i],u[i],w[i]);
            dijkstra(1);
            for(int i=2;i<=p;i++)ans+=d[i];
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code

     POJ 2502

    建好边,跑一遍最短路

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define pii pair<int,int>
    #define pdi pair<double,int>
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=205;
    const int INF=0x3f3f3f3f;
    struct node
    {
        double x,y;
    }a[N];
    double mp[N][N];
    double d[N];
    int cnt;
    void dijkstra(int s)
    {
        priority_queue<pdi,vector<pdi>,greater<pdi> >q;
        for(int i=0;i<cnt;i++)d[i]=INF;
        d[s]=0;
        q.push(pdi(0,s));
        while(!q.empty())
        {
            pdi p=q.top();
            q.pop();
            if(d[p.second]<p.first)continue;
            for(int i=0;i<cnt;i++)
            {
                if(d[i]>d[p.second]+mp[p.second][i])
                {
                    d[i]=d[p.second]+mp[p.second][i];
                    q.push(pdi(d[i],i));
                }
            }
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        double sx,sy,ex,ey;
        double x,y;
        //freopen("in.txt","r",stdin);
        cin>>sx>>sy>>ex>>ey;
        double prex=-1;
        double prey=-1;
        cnt=0;
        a[cnt].x=sx,a[cnt++].y=sy;
        while(cin>>x>>y)
        {
            if(x!=-1)a[cnt].x=x,a[cnt].y=y;
            if(prex!=-1&&x!=-1)
            {
                double t=sqrt((a[cnt].x-a[cnt-1].x)*(a[cnt].x-a[cnt-1].x)+(a[cnt].y-a[cnt-1].y)*(a[cnt].y-a[cnt-1].y))/40000;
                mp[cnt][cnt-1]=t;
                mp[cnt-1][cnt]=t;
            }
            if(x!=-1)cnt++;
            prex=x;
            prey=y;
        }
        a[cnt].x=ex;
        a[cnt++].y=ey;
        for(int i=0;i<cnt;i++)
        {
            for(int j=0;j<cnt;j++)
            {
                if(mp[i][j]>0)mp[i][j]=min(sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y))/10000,mp[i][j]);
                else mp[i][j]=sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y))/10000;
            }
        }
        dijkstra(0);
        cout<<(int)(d[cnt-1]*60+0.5)<<endl;
        //fclose(stdin);
        return 0;
    }
    View Code

     POJ 3159

    枚举能跑的点上下界

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define pii pair<int,int>
    #define pdi pair<double,int>
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=105;
    const int INF=0x3f3f3f3f;
    int n,m;
    struct edge
    {
        int to,w,next;
    }edge[N*N];
    int head[N];
    int level[N];
    int d[N];
    int x[N];
    int v[N][N];
    int t[N][N];
    int p[N];
    int cnt=0;
    void add_edge(int u,int v,int w)
    {
        edge[cnt].to=v;
        edge[cnt].w=w;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    void dijkstra(int s,int l,int r)
    {
        priority_queue<pii,vector<pii>,greater<pii> >q;
        mem(d,INF);
        d[s]=0;
        q.push(mp(0,s));
        while(!q.empty())
        {
            pii p=q.top();
            q.pop();
            if(d[p.second]<p.first)continue;
            for(int i=head[p.second];~i;i=edge[i].next)
            {
                if(l<=level[edge[i].to]&&level[edge[i].to]<=r&&d[edge[i].to]>d[p.second]+edge[i].w)
                {
                    d[edge[i].to]=d[p.second]+edge[i].w;
                    q.push(mp(d[edge[i].to],edge[i].to));
                }
            }
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin>>m>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>p[i]>>level[i]>>x[i];
            for(int j=0;j<x[i];j++)
            {
                cin>>t[i][j]>>v[i][j];
            }
        }
        mem(head,-1);
        cnt=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<x[i];j++)
            {
                    add_edge(i,t[i][j],v[i][j]);
            }
        }
        int ans=p[1];
        for(int l=level[1]-m;l<=level[1];l++)
        {
            dijkstra(1,l,l+m);
            for(int i=2;i<=n;i++)ans=min(ans,d[i]+p[i]);
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

     POJ 1847

    水水的一道最短路,把转动次数看成路径权值

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define pii pair<int,int>
    #define pdi pair<double,int>
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=105;
    const int INF=0x3f3f3f3f;
    int head[N];
    int d[N];
    int cnt;
    struct edge
    {
        int to,w,next;
    }edge[N*N];
    void add_edge(int u,int v,int w)
    {
        edge[cnt].to=v;
        edge[cnt].w=w;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    void dijkstra(int s)
    {
        priority_queue<pii,vector<pii>,greater<pii> >q;
        mem(d,INF);
        d[s]=0;
        q.push(mp(0,s));
        while(!q.empty())
        {
            pii p=q.top();
            q.pop();
            if(d[p.second]<p.first)continue;
            for(int i=head[p.second];~i;i=edge[i].next)
            {
                if(d[edge[i].to]>d[p.second]+edge[i].w)
                {
                    d[edge[i].to]=d[p.second]+edge[i].w;
                    q.push(mp(d[edge[i].to],edge[i].to));
                }
            }
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n,a,b,t,m;
        cin>>n>>a>>b;
        cnt=0;
        mem(head,-1);
        for(int i=1;i<=n;i++)
        {
            cin>>m;
            if(m)
            {
                m--;
                cin>>t;
                add_edge(i,t,0);
            }
            while(m--)
            {
                cin>>t;
                add_edge(i,t,1);
            }
        }
        dijkstra(a);
        if(d[b]!=INF)cout<<d[b]<<endl;
        else cout<<-1<<endl;
        return 0;
    }
    View Code

     LightOJ 1074

    不会spfa,看来要去学了,用dijkstra剪了一下枝,水过数据

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define pii pair<int,int>
    #define pdi pair<double,int>
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=205;
    const int INF=0x3f3f3f3f;
    int d[N];
    int a[N];
    int head[N];
    int cnt,n;
    struct edge
    {
        int to,w,next;
    }edge[N*N];
    void add_edge(int u,int v,int w)
    {
        edge[cnt].to=v;
        edge[cnt].w=w;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    void dijkstra(int s)
    {
        priority_queue<pii,vector<pii>,greater<pii> >q;
        mem(d,INF);
        d[s]=0;
        q.push(mp(0,s));
        while(!q.empty())
        {
            pii p=q.top();
            q.pop();
            if(d[p.second]<p.first)continue;
            for(int i=head[p.second];~i;i=edge[i].next)
            {
                if(d[edge[i].to]>d[p.second]+edge[i].w)
                {
                    d[edge[i].to]=d[p.second]+edge[i].w;
                    if(d[edge[i].to]>-10000)q.push(mp(d[edge[i].to],edge[i].to));
                }
            }
        }
    }
    bool bellman()
    {
        mem(d,0);
        for(int i=1;i<=n;i++)
        {
            bool upd=false;
            for(int j=0;j<cnt;j++)
            {
    
            }
            if(!upd)return false;
        }
        return false;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int T,m,q,cs=0,u,v,t;
        cin>>T;
        while(T--)
        {
            cin>>n;
            for(int i=1;i<=n;i++)cin>>a[i];
            cnt=0;
            mem(head,-1);
            cin>>m;
            while(m--)cin>>u>>v,add_edge(u,v,pow(a[v]-a[u],3));
            dijkstra(1);
            cout<<"Case "<<++cs<<":"<<endl;
            cin>>q;
            while(q--)
            {
                cin>>t;
                if(d[t]!=INF&&d[t]>=3)cout<<d[t]<<endl;
                else cout<<"?"<<endl;
            }
        }
        return 0;
    }
    View Code

    HDU 4725

    没有点的楼层之间不能建边,而且只能将同一层的点和所在楼层连单向边,不然同一层的点之间可以免费跑,wa到死

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define pii pair<int,int>
    #define pdi pair<double,int>
    #define pli pair<ll,int>
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=1e5+5;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    int head[2*N];
    bool vis[N];
    ll d[2*N];
    int l[N];
    int cnt;
    int n,c;
    struct edge
    {
        int to,w,next;
    }edge[10*N];
    void add_edge(int u,int v,int w)
    {
        edge[cnt].to=v;
        edge[cnt].w=w;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    void dijkstra(int s)
    {
        priority_queue<pli,vector<pli>,greater<pli> >q;
        mem(d,INF);
        d[s]=0;
        q.push(mp(0,s));
        while(!q.empty())
        {
            pli p=q.top();
            q.pop();
            if(d[p.second]<p.first)continue;
            for(int i=head[p.second];~i;i=edge[i].next)
            {
                if(d[edge[i].to]>d[p.second]+edge[i].w)
                {
                    d[edge[i].to]=d[p.second]+edge[i].w;
                    q.push(mp(d[edge[i].to],edge[i].to));
                }
            }
        }
    }
    int main()
    {
        int T,m,t,u,v,w,cs=0;
        scanf("%d",&T);
        while(T--)
        {
            cnt=0;
            mem(head,-1);
            mem(vis,false);
            scanf("%d%d%d",&n,&m,&c);
            for(int i=1;i<=n;i++)scanf("%d",&l[i]),vis[l[i]]=true;
            while(m--)scanf("%d%d%d",&u,&v,&w),add_edge(u,v,w),add_edge(v,u,w);
            for(int i=1;i<n;i++)if(vis[i]&&vis[i+1])add_edge(n+i,n+i+1,c),add_edge(n+i+1,n+i,c);
            for(int i=1;i<=n;i++)
            {
                add_edge(i,l[i]+n,0);
                if(l[i]>1)add_edge(i,l[i]-1+n,c),add_edge(l[i]-1+n,i,c);
                if(l[i]<n)add_edge(i,l[i]+1+n,c),add_edge(l[i]+1+n,i,c);
            }
            dijkstra(1);
            printf("Case #%d: ",++cs);
            if(d[n]!=INF)printf("%lld
    ",d[n]);
            else printf("-1
    ");
        }
        return 0;
    }
    View Code

     POJ 3169

    原来spfa这么简单

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=1e3+5;
    const int INF=0x3f3f3f3f;
    int d[N];
    int head[N];
    bool vis[N];
    int c[N];
    int n;
    int cnt;
    struct edge
    {
        int to,w,next;
    }edge[N*N];
    void add_edge(int u,int v,int w)
    {
        edge[cnt].to=v;
        edge[cnt].w=w;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    bool spfa(int s)
    {
        mem(d,INF);
        mem(c,0);
        mem(vis,false);
        d[s]=0;
        c[s]=1;
        vis[s]=true;
        queue<int>q;
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            vis[u]=false;
            for(int i=head[u];~i;i=edge[i].next)
            {
                if(d[edge[i].to]>d[u]+edge[i].w)
                {
                    d[edge[i].to]=d[u]+edge[i].w;
                    if(!vis[edge[i].to])
                    {
                        vis[edge[i].to]=true;
                        c[edge[i].to]++;
                        q.push(edge[i].to);
                        if(c[edge[i].to]>=n)
                        {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int L,D,a,b,c;
        cin>>n>>L>>D;
        mem(head,-1);
        cnt=0;
        while(L--)
        {
            cin>>a>>b>>c;
            add_edge(a,b,c);
        }
        while(D--)
        {
            cin>>a>>b>>c;
            add_edge(b,a,-c);
        }
        if(spfa(1))cout<<-1<<endl;
        else
        {
            if(d[n]==INF)cout<<-2<<endl;
            else cout<<d[n]<<endl;
        }
        return 0;
    }
    View Code

     HDU 4370

    两种情况,一种最短路,一种是从1和n分别出发的环(不包括自环)

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    const int N=305;
    const int INF=0x3f3f3f;
    int cost[N][N];
    int d[N];
    int c[N];
    bool vis[N];
    int n;
    bool spfa(int s)
    {
        mem(vis,false);
        mem(c,0);
        mem(d,0);
        queue<int>q;
        for(int i=1;i<=n;i++)
        {
            if(i==s)d[s]=INF,vis[s]=false;
            else d[i]=cost[s][i],q.push(i),vis[i]=true,c[i]=1;
        }
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            vis[u]=false;
            for(int i=1;i<=n;i++)
            {
                if(d[i]>d[u]+cost[u][i])
                {
                    d[i]=d[u]+cost[u][i];
                    if(!vis[i])
                    {
                        vis[i]=true;
                        q.push(i);
                        c[i]++;
                        if(c[i]>=n)return true;
                    }
                }
            }
        }
        return false;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        while(cin>>n)
        {
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    cin>>cost[i][j];
            spfa(1);
            int ans=d[n];
            int loop1=d[1];
            spfa(n);
            int loop2=d[n];
            cout<<min(ans,loop1+loop2)<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Jmeter ----关于上传图片接口
    JMeter学习笔记16-如何输出HTML格式的性能测试报告
    Robot Framework课件汇总
    Robot Framework自动化测试(七)--- jybot模式
    Robot Framework自动化测试(六)--- robotremoteserver使用
    Robot Framework自动化测试(四)--- 分层思想
    Robot Framework自动化测试(五)--- 开发系统关键字
    Robot Framework自动化测试(二)---元素定位
    威睿虚拟机 VMware Workstation Pro 15.1.0 中文版 + 注册机
    我眼中的java线程池实现原理
  • 原文地址:https://www.cnblogs.com/widsom/p/7295449.html
Copyright © 2011-2022 走看看