HDU-4522 湫湫系列故事——过年回家 最短路

题意:很乱

分析:把数据处理下,dijkstra下就行了,floyd超时了,我还想着优化一下输入,因为使用了vector和string等等,但是计算数据规模后,处理输入的时间复杂度比floyd要低一个数量级,看来还是要换成dijkstra了。

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;

const int N = 205;
const int inf = 0x3f3f3f3f; 
int n, m, D1, D2, A, B;
vector<string>vs[2];
int mp1[N][N];
int mp2[N][N];

void conn(int mp[][N], const string & s, int val) {
    int t = 0;
    vector<int>vt;
    for (int i = 0; i < s.length(); ++i) {
        if (s[i] != '+') t = t * 10 + s[i] - '0';
        else {
            vt.push_back(t);
            t = 0;
        }
    }
    vt.push_back(t);
    for (int i = 0; i < (int)vt.size(); ++i) {
        for (int j = i+1; j < (int)vt.size(); ++j) {
            mp[vt[i]][vt[j]] = min(mp[vt[i]][vt[j]], val*(j-i));
        }
    }
}

int dis[N];
char vis[N];

int dijkstra(int mp[][N]) {
    memset(dis, 0x3f, sizeof (dis));
    memset(vis, 0, sizeof (vis));
    dis[A] = 0;
    for (int i = 0; i < n; ++i) {
        int Min = inf, p;
        for (int j = 1; j <= n; ++j) {
            if (!vis[j] && Min > dis[j]) {
                Min = dis[j];
                p = j;
            }
        }
        if  (p == B) break;
        vis[p] = 1;
        for (int j = 1; j <= n; ++j) {
            if (!vis[j] && dis[p]+mp[p][j] < dis[j]) {
                dis[j] = dis[p] + mp[p][j];
            }
        }
    }
    return dis[B];
}

void solve() {
    memset(mp1, 0x3f, sizeof (mp1));
    memset(mp2, 0x3f, sizeof (mp2));
    for (int i = 0; i < (int)vs[0].size(); ++i) {
        conn(mp1, vs[0][i], D1);
    }
    for (int i = 0; i < (int)vs[1].size(); ++i) {
        conn(mp1, vs[1][i], D1);
        conn(mp2, vs[1][i], D2);
    }
    int ans = min(dijkstra(mp1), dijkstra(mp2));
    printf(ans == inf ? "-1\n" : "%d\n", ans);
}

int main() {
    int T, k;
    char str[10005];
    scanf("%d", &T);
    while (T--) {
        vs[0].clear();
        vs[1].clear();
        scanf("%d %d", &n, &m);
        for (int i = 0; i < m; ++i) {
            scanf("%s %d", str, &k);
            if (k == 0) vs[0].push_back(str);
            else vs[1].push_back(str);
        }
        scanf("%d %d %d %d", &D1, &D2, &A, &B);
        solve();
    }
    return 0;
}

 

posted @ 2013-11-07 15:47  沐阳  阅读(325)  评论(0编辑  收藏  举报