Invitation Cards POJ 1511 SPFA || dij + heap

http://poj.org/problem?id=1511

求解从1去其他顶点的最短距离之和。

加上其他顶点到1的最短距离之和。

边是单向的。

第一种很容易,直接一个最短路,

然后第二个,需要把边反向建一次,跑一个最短路就好。

★、cin  cout 超时

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
struct HeapNode {
    int u, dis;
    HeapNode(int from, int cost) : u(from), dis(cost) {}
    bool operator < (const struct HeapNode & rhs) const {
        return dis > rhs.dis;
    }
};
const int maxn = 1000000 + 20;
int book[maxn], DFN, dis[maxn];
int first[maxn], num;
struct Node {
    int u, v, w, tonext;
}e[maxn * 2];
void add(int u, int v, int w) {
    ++num;
    e[num].u = u, e[num].v = v, e[num].w = w;
    e[num].tonext = first[u];
    first[u] = num;
}
void dij(int bx, int n) {
    ++DFN;
    for (int i = 1; i <= n; ++i) dis[i] = inf;
    dis[bx] = 0;
    priority_queue<HeapNode> que;
    while (!que.empty()) que.pop();
    que.push(HeapNode(bx, dis[bx]));
    while (!que.empty()) {
        HeapNode t = que.top();
        que.pop();
        int u = t.u;
        if (book[u] == DFN) continue;
        book[u] = DFN;
        for (int i = first[u]; i; i = e[i].tonext) {
            int v = e[i].v;
            if (book[v] != DFN && dis[v] > dis[u] + e[i].w) {
                dis[v] = dis[u] + e[i].w;
                que.push(HeapNode(v, dis[v]));
            }
        }
    }
}
bool in[maxn], tim[maxn];
bool spfa(int bx, int n) { //从bx开始,有n个顶点
    for (int i = 1; i <= n; ++i) {
        dis[i] = inf;
        tim[i] = 0; //入队次数清0
        in[i] = false; //当前这个节点不在队列里
    }
    queue<int> que;
    while (!que.empty()) que.pop();
    que.push(bx), in[bx] = true, dis[bx] = 0, tim[bx]++;
    while (!que.empty()) {
        int u = que.front();
        if (tim[u] > n) return true; //出现负环
        que.pop();
        for (int i = first[u]; i; i = e[i].tonext) {
            if (dis[e[i].v] > dis[e[i].u] + e[i].w) {
                dis[e[i].v] = dis[e[i].u] + e[i].w;
                if (!in[e[i].v]) { //不在队列
                    que.push(e[i].v);
                    in[e[i].v] = true;
                    tim[e[i].v]++;
                }
            }
        }
        in[u] = false;
    }
    return false;
}
int u[maxn], v[maxn], w[maxn];
void init(int n) {
    for (int i = 1; i <= n; ++i) first[i] = 0;
    num = 0;
}
void work() {
    int n, m;
    scanf("%d%d", &n, &m);
    init(n);
    for (int i = 1; i <= m; ++i) {
//        cin >> u[i] >> v[i] >> w[i];
        scanf("%d%d%d", &u[i], &v[i], &w[i]);
        add(u[i], v[i], w[i]);
    }
    spfa(1, n);
    LL ans = 0;
    for (int i = 2; i <= n; ++i) ans += dis[i];
    init(n);
    for (int i = 1; i <= m; ++i) {
        add(v[i], u[i], w[i]);
    }
    spfa(1, n);
    for (int i = 2; i <= n; ++i) ans += dis[i];
    printf("%lld\n", ans);
}

int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    int t;
    scanf("%d", &t);
    while (t--) work();
    return 0;
}

时间: 2024-08-28 19:11:23

Invitation Cards POJ 1511 SPFA || dij + heap的相关文章

Invitation Cards POJ - 1511 spfa

//从起点1到剩余P-1个点的最短距离之和+从剩余P-1个点到起点1的最短距离之和 #include<iostream> #include<cstring> #include<cstdio> #include<queue> using namespace std; const int LEN=1000005; const int INF=0x3f3f3f3f; struct Edge{ int to, next; long long val; }edge[2

POJ1511 Invitation Cards —— 最短路spfa

题目链接:http://poj.org/problem?id=1511 Invitation Cards Time Limit: 8000MS   Memory Limit: 262144K Total Submissions: 29286   Accepted: 9788 Description In the age of television, not many people attend theater performances. Antique Comedians of Malidine

POJ 1511 Invitation Cards 邻接表 spfa算法

原题: http://poj.org/problem?id=1511 题目大意: 单向图,需要从点1到每个点去一次,去了马上回来,再去下一个点,求往返路径和. 如果只有100个点,跑一遍floyd就可以了,这里有10w个点,不行. 朴素的dijkstra是N^2的复杂度,这里要超时. 所以这里我们用spfa这种接近2N的算法. 由于二维数组空间不够,所以只能用vector或者邻接表,因为vector的适合经常修改,本身是链表结构,每次插入数据都会消耗时间来申请内存并和前面建立联系,虽然可以支持下

POJ 1511 SPFA+邻接表

#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include <vector> #include <queue> using namespace std; #define INF 0xffffffff #define maxn 1000005 struct Edge { int w, e; }; int UseCount[m

POJ 1511 Invitation Cards 【最短路,spfa算法,Dijkstra算法堆优化】

Invitation Cards Time Limit: 8000MS   Memory Limit: 262144K Total Submissions: 25219   Accepted: 8346 Description In the age of television, not many people attend theater performances. Antique Comedians of Malidinesia are aware of this fact. They wan

HDU 1535 &amp;&amp; POJ 1511 Invitation Cards (SPFA 模板 + 反向建图)

Invitation Cards HDU: Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) POJ: Time Limit: 8000 MS     Memory Limit: 262144 K       Problem Description In the age of television, not many people attend theater performa

(简单) POJ 1511 Invitation Cards,SPFA。

Description In the age of television, not many people attend theater performances. Antique Comedians of Malidinesia are aware of this fact. They want to propagate theater and, most of all, Antique Comedies. They have printed invitation cards with all

poj 1511 Invitation Cards (spfa+邻接表)

Invitation Cards Time Limit: 8000MS   Memory Limit: 262144K Total Submissions: 19527   Accepted: 6375 Description In the age of television, not many people attend theater performances. Antique Comedians of Malidinesia are aware of this fact. They wan

POJ 1511 Invitation Cards(逆向思维 SPFA)

Description In the age of television, not many people attend theater performances. Antique Comedians of Malidinesia are aware of this fact. They want to propagate theater and, most of all, Antique Comedies. They have printed invitation cards with all