1. 程式人生 > >PAT A1111 Online Map(30 分)----最短路徑麻煩題

PAT A1111 Online Map(30 分)----最短路徑麻煩題

總結:最後一個測試點超時。。

1.這道題因為兩個要求,同時求的話要互不影響才行,就像求最短路徑的時候不能更新時間(重新設定個變數更新)

2.以求最快路徑為例,當totalen<minlen一定要更新totalsize,否則結果可能出錯

3.這種題優先採用dijstra方法

程式碼:

#include<iostream>
#include<vector>
#include<map>
using namespace std;
int n, m;
int G[600][600];     //長度
int ti[600][600];
int vi[600];
int st, end1;
int minlen=999999, totalen=0;
int mintime = 999999, totaltime = 0;
int mintime1 = 999999, totaltime1 = 0;
int totalsize = 0, minsize = 999999;
map<int, vector<vector<int>>> zuiduan;
map<int, vector<vector<int>>> zuikuai;
void dfs(int index,vector<int>duan,vector<int>kuai)
{
    if (vi[index] == 1)return;
    if (index == end1)
    {
        if (totalen < minlen){ minlen = totalen; mintime1 = totaltime1; zuiduan[minlen].push_back(duan); }
        else if (totalen == minlen&&totaltime1 < mintime1){ mintime1 = totaltime1; minlen = totalen; zuiduan[minlen].push_back(duan); }
        if (totaltime < mintime){ mintime = totaltime; minsize = totalsize; zuikuai[mintime].push_back(kuai); }
        else if (totalsize<minsize&&totaltime == mintime){ minsize = totalsize; mintime = totaltime; zuikuai[mintime].push_back(kuai); }
    }
    vi[index] = 1;
    for (int i = 0; i < n; i++)
    {
        if (vi[i] == 0 && G[index][i] != 0&&ti[index][i]!=0)
        {
          if(totalen>minlen&&totaltime>mintime)continue;
            totalsize++;
            totaltime += ti[index][i];
            totalen += G[index][i];
            totaltime1 += ti[index][i];
            kuai.push_back(i);
            duan.push_back(i);
            dfs(i,duan,kuai);
            totalsize--;
            totalen -= G[index][i];
            totaltime -= ti[index][i];
            totaltime1 -= ti[index][i];
            kuai.pop_back(); duan.pop_back();
            vi[i] = 0;
        }
    }
}
int main()
{
    cin >> n >> m;
    for (int i = 0; i < m; i++)
    {
        int v1, v2, one, len, time;
        scanf("%d%d%d%d%d",&v1,&v2,&one,&len,&time);
        if (one == 1){ G[v1][v2] = len; ti[v1][v2] = time;  }
        else { G[v1][v2] = len; ti[v1][v2] = time; G[v2][v1] = len; ti[v2][v1] = time; }
    }
    cin >> st >> end1;
    vector<int> duan;
    vector<int> kuai;
    duan.push_back(st);
    kuai.push_back(st);
    dfs(st,duan,kuai);
    bool same = true;
    int k1 = zuiduan[minlen].size(); int k2 = zuikuai[mintime].size();
    if (zuiduan[minlen][zuiduan[minlen].size() - 1].size() == zuikuai[mintime][zuikuai[mintime].size() - 1].size())
    {
        for (int i = 0; i < zuiduan[minlen][zuiduan[minlen].size() - 1].size(); i++)
        {
            if (zuiduan[minlen][zuiduan[minlen].size() - 1][i] != zuikuai[mintime][zuikuai[mintime].size() - 1][i]){ same = false; break; }
        }
    }
    else same = false;
    if (same == true){
        cout << "Distance = " << minlen << "; Time = " << mintime << ": ";
        for (int i = 0; i < zuiduan[minlen][zuiduan[minlen].size() - 1].size(); i++)
        {
            printf("%d",zuiduan[minlen][zuiduan[minlen].size() - 1][i]);
            if (i != zuiduan[minlen][zuiduan[minlen].size() - 1].size() - 1)printf(" -> ");
        }
    }
    else{
        cout << "Distance = "<<minlen<<": ";
        for (int i = 0; i < zuiduan[minlen][zuiduan[minlen].size() - 1].size(); i++)
        {
            printf("%d", zuiduan[minlen][zuiduan[minlen].size() - 1][i]);
            if (i != zuiduan[minlen][zuiduan[minlen].size() - 1].size() - 1)printf(" -> ");
        }
        cout << endl;
        cout << "Time = "<<mintime<<": ";
        for (int i = 0; i < zuikuai[mintime][zuikuai[mintime].size() - 1].size(); i++)
        {
            printf("%d", zuikuai[mintime][zuikuai[mintime].size() - 1][i]);
            if (i != zuikuai[mintime][zuikuai[mintime].size() - 1].size() - 1)printf(" -> ");
        }
    }
    return 0;
}

參考程式碼:

#include <iostream>

#include <algorithm>

#include <vector>

using namespace std;

const int inf = 999999999;

int dis[510], Time[510], e[510][510], w[510][510], dispre[510],Timepre[510], weight[510],NodeNum[510];

bool visit[510];

vector<int> dispath, Timepath, temppath;

int st, fin, minnode = inf;

void dfsdispath(int v) {

    dispath.push_back(v);

    if(v == st) return ;

    dfsdispath(dispre[v]);

}

void dfsTimepath(int v) {

    Timepath.push_back(v);

    if(v == st) return ;

    dfsTimepath(Timepre[v]);

}

int main() {

    fill(dis, dis + 510, inf);

    fill(Time, Time + 510, inf);

    fill(weight, weight + 510, inf);

    fill(e[0], e[0] + 510 * 510, inf);

    fill(w[0], w[0] + 510 * 510, inf);

    int n, m;

    scanf("%d %d", &n, &m);

    int a, b, flag, len, t;

    for(int i = 0; i < m; i++) {

        scanf("%d %d %d %d %d", &a, &b, &flag, &len, &t);

        e[a][b] = len;

        w[a][b] = t;

        if(flag != 1) {

            e[b][a] = len;

            w[b][a] = t;

        }

    }

    scanf("%d %d", &st, &fin);

    dis[st] = 0;

    for(int i = 0; i < n; i++)

        dispre[i] = i;

    for(int i = 0; i < n; i++) {

        int u = -1, minn = inf;

        for(int j = 0; j < n; j++) {

            if(visit[j] == false && dis[j] < minn) {

                u = j;

                minn = dis[j];

            }

        }

        if(u == -1) break;

        visit[u] = true;

        for(int v = 0; v < n; v++) {

            if(visit[v] == false && e[u][v] != inf) {

                if(e[u][v] + dis[u] < dis[v]) {

                    dis[v] = e[u][v] + dis[u];

                    dispre[v] = u;

                    weight[v] = weight[u] + w[u][v];

                } else if(e[u][v] + dis[u] == dis[v] && weight[v] > weight[u] + w[u][v]) {

                    weight[v] = weight[u] + w[u][v];

                    dispre[v] = u;

                }

            }

        }

    }

    dfsdispath(fin);

    Time[st] = 0;

    fill(visit, visit + 510, false);

    for(int i = 0; i < n; i++) {

        int u = -1, minn = inf;

        for(int j = 0; j < n; j++) {

            if(visit[j] == false && minn > Time[j]) {

                u = j;

                minn = Time[j];

            }

        }

        if(u == -1) break;

        visit[u] = true;

        for(int v = 0; v < n; v++) {

            if(visit[v] == false && w[u][v] != inf) {

                if(w[u][v] + Time[u] < Time[v]) {

                    Time[v] = w[u][v] + Time[u];

                    Timepre[v]=(u);

                    NodeNum[v]=NodeNum[u]+1;

                } else if(w[u][v] + Time[u] == Time[v]&&NodeNum[u]+1<NodeNum[v]) {

                    Timepre[v]=(u);

                    NodeNum[v]=NodeNum[u]+1;

                }

            }

        }

    }

    dfsTimepath(fin);

    printf("Distance = %d", dis[fin]);

    if(dispath == Timepath) {

        printf("; Time = %d: ", Time[fin]);

    } else {

        printf(": ");

        for(int i = dispath.size() - 1; i >= 0; i--) {

            printf("%d", dispath[i]);

            if(i != 0) printf(" -> ");

        }

        printf("\nTime = %d: ", Time[fin]);

    }

    for(int i = Timepath.size() - 1; i >= 0; i--) {

        printf("%d", Timepath[i]);

        if(i != 0) printf(" -> ");

    }

    return 0;

}