最短路

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<deque>
using namespace std;
#define INF 0x3f3f3f3f
//单源最短路 Dijkstra
//复杂度 O(ElogE)
//最短路算法思想,总是优先扩展距离起点最近的点 
const int maxn=1000+5;
struct T{
    int from,to,cost;
    T(int a,int b,int c):from(a),to(b),cost(c){
    }
};
vector<T> vect;
vector<int> vp[maxn];//保存 
int dp[maxn];//距离 
int t,n;
struct HN{
    int dis,from;
    HN(int a,int b):dis(a),from(b){
    }
    bool operator <(const HN& h)const{
        return dis>h.dis;//距离起点最远的先出列 
    }
};
bool vis[maxn];//是否永久标号 
void DJ(int s){
    priority_queue<HN> pque;
    dp[s]=0;
    for(int i=1;i<n;i++)dp[i]=INF;
    memset(vis,false,sizeof(vis));
    pque.push(HN(dp[s],s));
    while(!pque.empty()){
        HN hn=pque.top();pque.pop();
        int u=hn.from;
        if(vis[u])continue;
        vis[u]=true; 
        for(int i=0;i<vp[u].size();i++){
            T e=vect[vp[u][i]];
            if(dp[e.to]>dp[e.from]+e.cost){
                dp[e.to]=dp[e.from]+e.cost;
                pque.push(HN(dp[e.to],e.to));
            }
        }
    }
}
int main(){
    int a,b,c;
    cin>>t>>n;
    while(t--){
        cin>>a>>b>>c;
        vect.push_back(T(a,b,c));
        vect.push_back(T(b,a,c));
        vp[a].push_back(vect.size()-2);
        vp[b].push_back(vect.size()-1);
    }
    DJ(n);
    cout<<dp[1]<<endl;
    return 0;
} 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
//单源最短路 有负权 Bellman_ford
//复杂度 O(VE)
#define INF 0x3f3f3f3f
const int maxn =500+5;
struct Edge{
    int from,to,dis;
    Edge(int a,int b,int c):from(a),to(b),dis(c){
    }
}; 
vector<Edge> edges;
vector<int> G[maxn];
int T,N,M,K;
vector<int> vect;
int cnt[maxn],inq[maxn],d[maxn];
int jud;
bool BF(int s){
    queue<int> que;
    memset(inq,0,sizeof(inq));
    memset(cnt,0,sizeof(cnt));
    for(int i=1;i<=N;i++)d[i]=INF;
    d[s]=0,inq[s]=true,que.push(s);
    while(!que.empty()){
        int u=que.front();que.pop();
        inq[u]=false;
        for(int i=0;i<G[u].size();i++){
            Edge& e=edges[G[u][i]];
            if(d[u]<INF&&d[e.to]>d[u]+e.dis){
                d[e.to]=d[u]+e.dis;
                if(d[s]<0){
                    jud=1;
                    return true;
                }
                if(!inq[e.to]){
                    que.push(e.to);
                    inq[e.to]=true;
                    if(++cnt[u]>N)return false;
                }
            }
        }
    }
    return true;
}
void init(){
    vect.clear();
    edges.clear();
    for(int i=0;i<=maxn;i++)
        G[i].clear();
}
int main(){
    int a,b,c;
    scanf("%d",&T);
    while(T--){
        init();
        scanf("%d%d%d",&N,&M,&K);
        for(int i=1;i<=M;i++){
            scanf("%d%d%d",&a,&b,&c);
            edges.push_back(Edge(a,b,c));
            edges.push_back(Edge(b,a,c));
            G[a].push_back(edges.size()-2);
            G[b].push_back(edges.size()-1);
        }
        for(int i=1;i<=K;i++){
            scanf("%d%d%d",&a,&b,&c);
            edges.push_back(Edge(a,b,-c));
            G[a].push_back(edges.size()-1);
            vect.push_back(a);
        }
        for(int i=0;i<K;i++){
            jud=0;
            BF(vect[i]);
            if(jud){
                cout<<"YES"<<endl;
                goto label; 
            }
        }
        printf("NO\n");
        label:;
    }
} 
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std ;


const int maxn = 1e2 + 10 ;

//多源最短路 | 任意两点之间的最短路问题  Floyd 算法
//状态转移方程 dis[i][j] = min( dis[i,k] + dis[k , j ] , dis[i][j] )
//复杂度 O(n^3) 

const int INF= 0x3f3f3f3f ;
int M , N  ;//边的个数和节点个数
int dis[maxn][maxn] ; 

void FL(){
    //插入点k 
    for(int k = 0 ;k<=N; k++)
        for(int i = 0 ;i<=N; i++)
            for(int j = 0 ; j<=N ;j++)
                dis[i][j] = min( dis[i][j] , dis[i][k] +dis[k][j]) ;
}
void ini(int n ){
    for(int i = 0 ;i<=n ; i++)
        for(int j = 0 ;j<=n; j ++)
            if( i == j )
                dis[i][j] = 0 ;
            else
                dis[i][j] = INF;

}

int main(){
    cin>>M >>N;
    ini(N) ;
    for(int i = 0 ;i<M ;i++){
        int a , b ,c ;
        cin>>a>>b >> c;
        dis[a][b] = c ;
        dis[b][a] = c ;
    } 
    FL() ;

    for(int i = 0 ;i<=N ; i ++){
        for(int j = 0 ;j<=N; j ++){
            cout<<dis[i][j]<<" " ;
        }
        cout<<endl;
    }
}
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std ;

//单源最短路 SPFA 
//可以判断是否有负环的存在、
//复杂度O(KE) 

const int maxn = 1e3 + 10 ;
const int INF = 0x3f3f3f3f ;
struct Edge{
    int v , cost ;
    Edge(int a , int b ): v(a ) , cost( b){
    } 
};
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 ] ;
queue<int> que ;

bool SPFA( int start , int n){
    memset( vis , false , sizeof( vis)) ;
    memset( cnt , 0 , sizeof( cnt )) ;
    for(int i =1 ; i<= n ; i ++)
        dis[i] = INF ;
    while( !que.empty())
        que.pop() ;

    vis[start] = true ;
    dis[start] = 0 ;
    cnt[start] = 1 ;
    que.push( start ) ;
    while( !que.empty()){
        int u = que.front()  ;
        que.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 ;
                    que.push( v ) ;
                    //入队次数不小于n
                    if( ++ cnt[v] > n )
                        return false ; 
                }
            }
        }
    }
    return true ;
}

//多源最短路转变成单源最短路问题可以添加一个源点0,他到任意其他起点的距离为0,跑一遍单源最短路算法,就可以将多源最短路问题转换成单源最短路问题 
vector<int> vect ;
int main(){
    int T , S , D ;
    int n ;
    while(cin>>T>>S>>D ){
        memset(E , 0 , sizeof( E)) ;
        vect.clear() ;

        for(int i = 0 ;i<T ;i++){
            int a , b , cost ;
            cin>> a >> b >> cost ;
            addEdge( a , b , cost ) ;
            addEdge( b , a , cost ) ;
            n = max( max ( a , b ) , n ) ;
        }

        for(int i = 0 ;i<S ;i++){
            int a ;
            cin>>a ;
            addEdge( a , 0 , 0 ) ;
            addEdge( 0 , a , 0 ) ;
        }

        for(int i = 0 ;i< D;i++){
            int a ;
            cin >> a ;
            vect.push_back( a ) ;
        }

        SPFA( 0 , n + 1 ) ;

        int ans = INF;
        for(int i = 0 ;i<vect.size() ;i++){
            ans = min( ans , dis[ vect[i] ]) ;
        }
        cout<<ans <<endl;
    } 
    return 0 ; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值