图论 之 最短路(Dijkstra and Floyd)


dijkstra


OJ题目:click here~~

题目分析:从0点出发,走遍能走的点的最短路径,可回头。dijkstra算法的变形,求0点出发的能到达的点的最短路径的最大值。2*总路径-最大值 即为要求的值

我只能说,写代码这事,不能停,停了就忘,忘了就出现bug,然后就陷入深深的debug中。。。被折磨的很惨很惨。。

AC_CODE

const int maxn = 52 ;
const int inf = 1<<30 ;
struct Node{
    int to , d ;
    Node(){}
    Node(int a , int b):to(a),d(b){}
    friend bool operator<(const Node &A , const Node &B){
        return A.d > B.d ;
    }
};
int dis[maxn][maxn] ;
vector g[maxn] ;
int mind[maxn] ;//0点到其他点的最短路径
int dijkstra(){
    int i , j ;
    priority_queue que ;
    que.push(Node(0 , 0)) ;
    mind[0] = 0 ;
    while(!que.empty()){
        Node now = que.top() ; que.pop() ;
        int u = now.to ;
        if(mind[u] < now.d) continue ;
        for(int i = 0;i < g[u].size();i++){
            int v = g[u][i] ;
            if(mind[v] > now.d + dis[u][v]){
                mind[v] = now.d + dis[u][v] ;
                que.push(Node(v , mind[v])) ;
            }
        }
    }
    int ans = 0 ;
    for(int i = 0;i < maxn;i++){
        if(mind[i] != inf)
            ans = max(ans , mind[i]) ;
    }
    return ans ;
}

int main(){
    int n , u , v , x , i , j ;
    int sum ;
    //freopen("in.txt","r",stdin) ;
    while(scanf("%d",&n) != EOF){
        sum = 0 ;
        fill(mind , mind + maxn , inf) ;
        for(i = 0;i < maxn;i++)
            g[i].clear() ;
        for(i = 0;i < n;i++){
            scanf("%d%d%d",&u,&v,&x) ;
            g[u].push_back(v) ;
            g[v].push_back(u) ;
            dis[u][v] = dis[v][u] = x ;
            sum += x ;
        }
        int ans = dijkstra() ;
        printf("%d\n",2*sum - ans) ;
    }
    return 0 ;
}

OJ题目:click here~~

题目分析:基本的dijkstra算法,多了一个花费,在路径相等时  根据 花费更新即可

AC_CODE

const int maxn = 1008 ;
const int inf = 1<<30 ;
vector g[maxn] ;
int len[maxn][maxn] ;
int cost[maxn][maxn] ;
int dis[maxn] ;
int val[maxn] ;
int vis[maxn] ;
int s , t ;
typedef pair pii ;
void dijkstra(){
    priority_queue , greater > que ;
    que.push(make_pair(0 , s)) ;
    while(!que.empty()){
        pii now = que.top() ; que.pop() ;
        int u = now.second ;
        if(dis[u] < now.first) continue ;
        for(int i = 0;i < g[u].size();i++){
            int v = g[u][i] ;
            if(dis[v] > dis[u] + len[u][v]){
                dis[v] = dis[u] + len[u][v] ;
                val[v] = val[u] + cost[u][v] ;//printf("%d~~~~",val[v]) ;
                que.push(make_pair(dis[v] , v)) ;
            }
            else if(dis[v] == dis[u] + len[u][v] && val[v] > val[u] + cost[u][v]){
                val[v] = val[u] + cost[u][v] ;
                que.push(make_pair(dis[v] , v)) ;
            }
        }
    }
}

int main(){
    int n , m , i , j , u , v , d , c;
    //freopen("in.txt","r",stdin) ;
    while(cin >> n >> m){
        if(n == 0 && m == 0) break ;
        for(i = 0;i < maxn;i++) g[i].clear() ;
        fill(dis , dis + maxn , inf) ;
        fill(val , val + maxn , inf) ;
        for(i = 0;i < m;i++){
            scanf("%d%d%d%d",&u,&v,&d,&c) ;
            g[u].push_back(v) ;
            g[v].push_back(u) ;
            len[u][v] = len[v][u] = d ;
            cost[u][v] = cost[v][u] = c ;
        }
        scanf("%d%d",&s,&t) ;
        dis[s] = val[s] = 0 ;
        dijkstra() ;
        printf("%d %d\n",dis[t],val[t]) ;
    }
}


OJ题目: click here~~

题目分析:就是dijkstsra,但是距离太大,不能用数表示,转化成string来处理

AC_CODE

const int maxn = 108 ;
const int maxm = 508 ;
const int MOD = 100000 ;
int n , m ;
string dis[maxn] ;
int cost[maxn][maxn] ;
int vis[maxn] ;
vector g[maxn] ;
 
struct Node{
    string len ;
    int p ;
    Node(){
        len = string(m , '0') ;
    }
    bool friend operator<(const Node &A , const Node &B){
        return A.len > B.len ;
    }
};
 
void bfs(){
    priority_queue que ;
    Node nu = Node() ;
    nu.p = 0 ;
    que.push(nu) ;
    int i , j  ;
    while(!que.empty()){
        Node now = que.top() ; que.pop() ;
        int u = now.p ;
        vis[u] = 1 ;
        for(i = 0;i < g[u].size() ;i++){
            int v = g[u][i] ;
            if(vis[v]) continue ;
            string nowstr = now.len ;
            nowstr[cost[u][v]] = '1' ;
            if(dis[v] > nowstr){
                dis[v] = nowstr ;
                Node nuu = Node() ;
                nuu.p = v ;
                nuu.len = nowstr ;
                que.push(nuu) ;
            }
        }
    }
    return ;
}
 
int cal(string s){
    int ans = 0 ;
    for(int i = 0;i < m;i++){
        ans = (ans*2 + (s[i] - '0'))%MOD ;
    }
    return ans ;
}
 
int main(){
    int i , j , k , u , v ;
    while(cin >> n >> m){
        for(i = 0;i < maxn;i++) g[i].clear() ;
        for(i = 0;i < n;i++){
            dis[i] = string(m , '2') ;
        }
        memset(vis , 0 , sizeof(vis)) ;
        for(i = 0;i < m;i++){
            scanf("%d%d" , &u , &v) ;
            g[u].push_back(v) ;
            g[v].push_back(u) ;
            cost[u][v] = cost[v][u] = m - 1 - i ;
        }
        dis[0] = string(m , '0') ;
        bfs() ;
        string ss = string(m , '2') ;
        for(i = 1;i < n;i++){
            if(dis[i] == ss) puts("-1") ;
            else cout << cal(dis[i]) << endl ;
        }
    }
    return 0 ;
}


你可能感兴趣的:(C++,图论,OJ)