算法设计课程复习(8)-最短路径

最短路径

这里的最短路径算法是bellman算法,同时可以判断该图有没有正权回路或者负权回路
Currency Exchange
AC代码

#include <iostream>
#include <cstdio>
#include <cstring>
#define Max 1000
using namespace std;
struct edge {
    int A, B;
    double r, c;
}edges[Max];
double dist[Max];

bool Bellman(int n, int m, int S, double V) {	//n是总点数,m是总边数,S是源点
    memset(dist, 0, sizeof(dist));
    dist[S] = V;
    for(int i=0; i<n-1; i++) {
        bool flag = false;
        for(int j=0; j<m; j++) {
            if(dist[edges[j].B] < (dist[edges[j].A]-edges[j].c)*edges[j].r) {
                dist[edges[j].B] = (dist[edges[j].A]-edges[j].c)*edges[j].r;
                flag = true;
            }
        }
        if(flag == false) return false;
    }
    for(int j=0; j<m; j++) {
        if(dist[edges[j].B] < (dist[edges[j].A]-edges[j].c)*edges[j].r) {
            return true;
        }
    }
    return false;
}

int main(int argc, const char * argv[]) {
    // insert code here...
    int N, M, S;
    double V;
    scanf("%d%d%d%lf", &N, &M, &S, &V);
    int total = 0;
    for(int i=0; i<M; i++) {
        int A, B;
        double r1, r2, c1, c2;
        scanf("%d%d%lf%lf%lf%lf", &A, &B, &r1, &c1, &r2, &c2);
        edges[total].A = A;
        edges[total].B = B;
        edges[total].r = r1;
        edges[total++].c = c1;
        edges[total].A = B;
        edges[total].B = A;
        edges[total].r = r2;
        edges[total++].c = c2;
    }
    if(Bellman(N, total, S, V) == true) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
    return 0;
}

Invitation Card

#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
#define Max 100
#define INF 0x3f3f3f3f
using namespace std;
int dist[Max];
int visited[Max];
int edges[Max][Max];
typedef pair<int, int> P;

int DJ(int s, int n) {
    priority_queue<P, vector<P>, greater<P>> que;
    for(int i=1; i<=n; i++) {
        dist[i] = INF;
        visited[i] = 0;
    }
    dist[s] = 0;
    que.push(P(dist[s], s));
    while(!que.empty()) {
        P p = que.top();
        que.pop();
        int u = p.second;
        if(visited[u] == 0) {
            visited[u] = 1;
            for(int i=1; i<=n; i++) {
                if(edges[u][i] != -1) {
                    if(dist[i] > dist[u] + edges[u][i]) {
                        dist[i] = dist[u] + edges[u][i];
                        que.push(P(dist[i],i));
                    }
                }
            }
        }
    }
    int res = 0;
    for(int i=1; i<=n; i++) {
        res += dist[i];
    }
    return res;
}
void change(int n) {
    int temp;
    for(int i=1; i<=n; i++) {
        for(int j=i+1; j<=n; j++) {
            temp = edges[i][j];
            edges[i][j] = edges[j][i];
            edges[j][i] = temp;
        }
    }
}

int main(int argc, const char * argv[]) {
    // insert code here...
    int N;
    scanf("%d", &N);
    while(N--) {
        int P, Q;
        scanf("%d%d", &P, &Q);
        memset(edges, -1, sizeof(edges));
        while(Q--) {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            edges[u][v] = w;
        }
        int res1 = DJ(1, P);
        change(P);
        int res2 = DJ(1, P);
        cout<<res1+res2<<endl;
        //cout<<result<<endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值