POJ - 1511Invitation Cards

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 the necessary information and with the programme. A lot of students were hired to distribute these invitations among the people. Each student volunteer has assigned exactly one bus stop and he or she stays there the whole day and gives invitation to people travelling by bus. A special course was taken where students learned how to influence people and what is the difference between influencing and robbery.
求出源點到所有點的最短距離與所有點到源點的最短距離,求和。
求完源點到所有點最短距離後將邊反向,再求一遍源點到所有點最短距離,求和即可。
數據量較大,直接求超時。我用到了spfa鄰接表
cin會超時,用scanf

#include<queue>
#include<stdio.h>
#include<string>
#include<iostream>
/*#include<map>
#include<limits>
#include<math.h>
*/
using namespace std;
#define N 1000000+2
#define LL long long int
#define pow(a) ((a)*(a))
#define INF 0x3f3f3f3f
#define mem(arr,a) memset(arr,a,sizeof(arr))
int t;
int n, m;
int d[N];
int headlist[2][N];
int vis[N];

struct edge{
    int to, cost;
    int next;
};
edge es[2][N];
int k;

void spfa(int s){

    for (int i = 1; i <= n; i++){
        d[i] = INF;
        vis[i] = 0;
    }
    d[1] = 0;
    queue<int> q;
    q.push(1);
    while (!q.empty()){
        int x = q.front(); q.pop();
        for (int i = headlist[s][x]; i; i = es[s][i].next){
            edge e = es[s][i];
            if (d[e.to] > d[x] + e.cost){
                d[e.to] = d[x] + e.cost;
                if (!vis[e.to]){
                    vis[e.to] = 1;          
                    q.push(e.to);
                }
            }
        }
        vis[x] = 0;
    }
}
int main(){
    cin >> t;
    while (t--){
        mem(es, 0);
        mem(headlist, 0);
        cin >> n >> m;
        k = 1;
        for (int i = 0; i < m; i++){
            int a, b, c;
            scanf("%d%d%d", &a, &b, &c);
            es[0][k].to = b;
            es[0][k].cost = c;
            es[0][k].next = headlist[0][a];
            headlist[0][a] = k;
            es[1][k].to = a;
            es[1][k].cost = c;
            es[1][k].next = headlist[1][b];
            headlist[1][b] = k++;
        }
        LL sum = 0;
        for (int i = 0; i < 2; i++){
            spfa(i);
            for (int j = 1; j <= n; j++){
                sum += d[j];
            }
        }
        cout << sum << endl;
    }
}

這種表的方式總是寫不慣…
存表

            /*a起點b終點c邊*/
            es[k].to = b;
            es[k].cost = c;
            es[k].next = headlist[a];
            headlist[a] = k++;

找表

//x源點
for (int i = headlist[x]; i; i = es[i].next)

i爲邊的編號,通過循環不斷找到x的臨邊。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章