首页 > 代码库 > 东大OJ1171题:ACMER的出行计划

东大OJ1171题:ACMER的出行计划

Problem Description

众所周知,ACMER经常要到全国各地去参加各种比赛。

每当要出去比赛的时候,我们先要制定一个出行计划,比如说我们是坐飞机还是坐火车,从哪里坐到哪里等等。

现在给你一副路线图,请你制定一个合理的出行计划,由于经费有限,规定最多只能坐k次飞机。

Input

第一行给出一个T,表示有T组数据,之后每组数据第一行分别给出n,m,k(n为点数,分别编号为1-n。m为单向边数)

接下来的m行每行分别给出u,v,w,x(u和v分别为两端点编号,方向为u->v。w为费用。x为类型,0表示火车,1表示飞机)

最后一行给出s,e(s为起点,e为终点)

数据范围:1 <= T <= 10; 1 <= n <= 1000; 1 <= m <= 10000; 0 < k < 10; 1 <= u,v <= n; 1 <= w <= 10000。所有数据都为整数

Output

对于每组数据,输出一行最少费用。

Sample Input
1 4 4 1 1 2 1 1 2 4 1 1 1 3 1 0 3 4 2 0 1 4
Sample Output
3
Source
岑榕
Hint
No Hint!
 
带限制求最短路
仔细想想发现是dijkstra的时候把在struct里加上cur表示飞了cur次
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1007, maxm = 10007, INF = 2147483467;
int first[maxn], vis[maxn][12], dis[maxn][12];
int u[maxm], v[maxm], w[maxm], fly[maxm], next[maxm];
int n, m, k, s, e;
struct state
{
    int x, d, cur;
    state(){}
    state(int x, int d, int cur): x(x), d(d), cur(cur){}
    bool operator < (const state& WTF)const
    {
       return d > WTF.d;
    }
};
void ini()
{
    memset(vis, 0, sizeof(vis));
    memset(first, -1, sizeof(first));
    for(int i = 0; i <= n; i++)
        for(int j = 0; j < 12; j++)
            dis[i][j] = INF;
}

void dij()
{
    priority_queue<state> Q;
    dis[s][0] = 0;
    state ST(s, 0, 0);
    Q.push(ST);
    while(!Q.empty())
    {
        state y = Q.top();
        Q.pop();
        int x = y.x;
        int cur = y.cur;
        if(x == e)
            break;
        if(vis[x][cur])
            continue;
        vis[x][cur] = 1;
        for(int i = first[x]; ~i; i = next[i])
        {
            if(cur+fly[i] > k)
                continue;
            if(dis[v[i]][cur+fly[i]] > dis[x][cur] + w[i])
            {
                dis[v[i]][cur+fly[i]] = dis[x][cur] + w[i];
                Q.push(state(v[i], dis[v[i]][cur+fly[i]], cur+fly[i]));
            }
        }
    }
    int ans = INF;
    for(int i = 0; i <= k; i++)
        ans = min(ans, dis[e][i]);
    printf("%d\n", ans);
}

int main()
{
    //freopen("in.txt", "r", stdin);
    int t;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d%d%d", &n, &m, &k);
        ini();
        for(int i = 0; i < m; i++)
        {
            scanf("%d%d%d%d", u+i, v+i, w+i, fly+i);
            next[i] = first[u[i]];
            first[u[i]] = i;
        }
        scanf("%d%d" ,&s, &e);
        dij();
    }
    return 0;
}

技术分享

东大OJ1171题:ACMER的出行计划