图论 最短路 邮递员送信

题目链接

LG P1629

题解

题意

找到任意两点的最短路,求和。

思路

  1. Floyd 看一下数据范围,超时警告(在不使用奇技淫巧的情况下)。
  2. 别的没尝试,数据范围比较大,稳妥一点使用了Dij。建立反向图,正向一遍反向一遍,求和就好。

AC代码

#include <bits/stdc++.h>

using namespace std;
//#pragma GCC optimize(2)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ull unsigned long long
#define ll long long
#define rep(i, x, y) for(int i=x;i<=y;i++)
#define mms(x, n) memset(x, n, sizeof(x))
#define mmc(A, tree) memcpy(A, tree, sizeof(tree))
#define eps (1e-8)
#define PI (acos(-1.0))
#define INF (0x3f3f3f3f)
#define mod (ull)(1e9+7)
typedef pair<int, int> P;

inline int read() {
    
    
    char a = 0;
    int x = 0, w = 1;
    while (a < '0' || a > '9') {
    
    
        if (a == '-')w = -1;
        a = getchar();
    }
    while (a >= '0' && a <= '9') {
    
    
        x = (x << 3) + (x << 1) + (a ^ 48);
        a = getchar();
    }
    return x * w;
}

const int N = 1e3 + 10, M = 1e5 + 10;
struct E {
    
    
    int to, ne, w;
} e[M], fe[M];
int head[M], cnt = 1;
int fhead[M], fcnt = 1;

void add(int u, int v, int w) {
    
    
    e[cnt].w = w;
    e[cnt].ne = head[u];
    e[cnt].to = v;
    head[u] = cnt++;
}

void fadd(int u, int v, int w) {
    
    
    fe[fcnt].w = w;
    fe[fcnt].ne = fhead[u];
    fe[fcnt].to = v;
    fhead[u] = fcnt++;
}

int d[N], fd[N];
int n, m;
int vis[N], fvis[N];

void dij() {
    
    
    for (int i = 1; i <= n; i++) {
    
    
        d[i] = INF;
    }
    d[1] = 0;
    while (true) {
    
    
        int u = -1;
        for (int i = 1; i <= n; i++) {
    
    
            if (!vis[i] && (u == -1 || d[i] < d[u])) u = i;
        }
        if (u == -1) break;
        vis[u] = 1;
        for (int i = head[u]; i; i = e[i].ne) {
    
    
            int v = e[i].to, w = e[i].w;
            if (d[v] > d[u] + w) {
    
    
                d[v] = d[u] + w;
            }
        }
    }
}

void fdij() {
    
    
    for (int i = 1; i <= n; i++) {
    
    
        fd[i] = INF;
    }
    fd[1] = 0;
    while (true) {
    
    
        int u = -1;
        for (int i = 1; i <= n; i++) {
    
    
            if (!fvis[i] && (u == -1 || fd[i] < fd[u])) u = i;
        }
        if (u == -1) break;
        fvis[u] = 1;
        for (int i = fhead[u]; i; i = fe[i].ne) {
    
    
            int v = fe[i].to, w = fe[i].w;
            if (fd[v] > fd[u] + w) {
    
    
                fd[v] = fd[u] + w;
            }
        }
    }
}

int main() {
    
    
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    mms(head, 0);
    mms(fhead, 0);
    n = read();
    m = read();
    for (int i = 1; i <= m; i++) {
    
    
        int u, v, w;
        u = read();
        v = read();
        w = read();
        add(u, v, w);
        fadd(v, u, w);
    }
    dij();
    fdij();
    int sum = 0;
    for (int i = 2; i <= n; i++) {
    
    
        sum += d[i] + fd[i];
    }
    printf("%d", sum);
    return 0;
}

后记

这个题真的。。让我有些迷惑。
刚开始用的是堆优化的dij,然后会一直在最后一个测试用例tle,这就很迷惑了。。如果有大佬的话还请赐教呀。

TLE代码

#include <bits/stdc++.h>

using namespace std;
//#pragma GCC optimize(2)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ull unsigned long long
#define ll long long
#define rep(i, x, y) for(int i=x;i<=y;i++)
#define mms(x, n) memset(x, n, sizeof(x))
#define mmc(A, tree) memcpy(A, tree, sizeof(tree))
#define eps (1e-8)
#define PI (acos(-1.0))
#define INF (0x3f3f3f3f)
#define mod (ull)(1e9+7)
typedef pair<int, int> P;
inline int qr()
{
    char a=0;int x=0,w=1;
    while(a<'0'||a>'9'){if(a=='-')w=-1;a=getchar();}
    while(a>='0'&&a<='9'){x=(x<<3)+(x<<1)+(a^48);a=getchar();}
    return x*w;
}
const int N = 1e3 + 10, M = 1e5 + 10;
struct E {
    int to, ne, w;
} e[M], fe[M];
int head[M], cnt = 1;
int fhead[M], fcnt = 1;

void add(int u, int v, int w) {
    e[cnt].w = w;
    e[cnt].ne = head[u];
    e[cnt].to = v;
    head[u] = cnt++;
}

void fadd(int u, int v, int w) {
    fe[fcnt].w = w;
    fe[fcnt].ne = fhead[u];
    fe[fcnt].to = v;
    fhead[u] = fcnt++;
}

int d[N], fd[N];
int n, m;

void dij() {
    for (int i = 1; i <= n; i++) {
        d[i] = INF;
    }
    priority_queue<P> q;
    q.push(P(0, 1));
    d[1] = 0;
    while (!q.empty()) {
        int x = q.top().second, di = q.top().first;
        q.pop();
        if (di > d[x]) continue;
        for (int j = head[x]; j; j = e[j].ne) {
            int i = e[j].to;
            if (d[i] > e[j].w + d[x]) {
                d[i] = e[j].w + d[x];
                q.push(P(d[i], i));
            }
        }
    }
}

void fdij() {
    for (int i = 1; i <= n; i++) {
        fd[i] = INF;
    }
    priority_queue<P> q;
    q.push(P(0, 1));
    fd[1] = 0;
    while (!q.empty()) {
        int x = q.top().second, di = q.top().first;
        q.pop();
        if (di > fd[x]) continue;
        for (int j = fhead[x]; j; j = fe[j].ne) {
            int i = fe[j].to;
            if (fd[i] > fe[j].w + fd[x]) {
                fd[i] = fe[j].w + fd[x];
                q.push(P(fd[i], i));
            }
        }
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    mms(head, 0);
    mms(fhead, 0);
    n = qr(); m = qr();
    for (int i = 1; i <= m; i++) {
        int u, v, w;
        u = qr();v = qr(); w = qr();
        add(u, v, w);
        fadd(v, u, w);
    }
    dij();
    fdij();
    int sum = 0;
    for (int i = 2; i <= n; i++) {
        sum += d[i] + fd[i];
    }
    printf("%d", sum);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45934120/article/details/108648732