UVA-11280 Flying to Fredericton (dijkstra)

题目大意:一张有向图,n个节点,m条边,有边权。求从起点到终点在最多经过s个中间节点(不包括始末点)时的最小权和。

题目分析:因为起点和终点是固定的,只需一次dijkstra打出表dis[u][k],查表即可。dis[u][k]表示经过k个中间节点到达u点时的最小费用。要注意,经过的中间节点数不会超过n。

代码如下:

# include<iostream>
# include<cstdio>
# include<map>
# include<vector>
# include<string>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std;
# define REP(i,s,n) for(int i=s;i<n;++i)
# define CL(a,b) memset(a,b,sizeof(a))

const int N=105;
const int INF=1<<30;
struct Edge
{
    int to,nxt,w;
};
Edge e[N*20];
int inq[N][N],dis[N][N],head[N],n,m,cnt;
map<string,int>mp;
struct Node
{
    int u,k;
    Node(int _u,int _k):u(_u),k(_k){}
};

void dijkstra(int s)
{
    REP(i,1,n+2) REP(j,0,n+2) dis[i][j]=INF;
    CL(inq,0);
    queue<Node>q;
    q.push(Node(s,0));
    dis[s][0]=0;
    inq[s][0]=1;
    while(!q.empty())
    {
        Node top=q.front();
        q.pop();
        int u=top.u,k=top.k;
        inq[u][k]=0;
        for(int i=head[u];i!=-1;i=e[i].nxt){
            int v=e[i].to;
            if(dis[v][k+1]>dis[u][k]+e[i].w){
                dis[v][k+1]=dis[u][k]+e[i].w;
                if(!inq[v][k+1]){
                    inq[v][k+1]=1;
                    q.push(Node(v,k+1));
                }
            }
        }
    }
}

void add(int u,int v,int w)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].nxt=head[u];
    head[u]=cnt++;
}

int main()
{
    int T,w,query,cas=0;
    string p,q;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        mp.clear();
        cnt=0;
        CL(head,-1);

        REP(i,1,n+1){
            cin>>p;
            mp[p]=i;
        }
        scanf("%d",&m);
        while(m--)
        {
            cin>>p>>q>>w;
            add(mp[p],mp[q],w);
        }
        printf("Scenario #%d\n",++cas);
        int s=mp["Calgary"],t=mp["Fredericton"];
        dijkstra(s);
        scanf("%d",&query);
        while(query--)
        {
            scanf("%d",&w);
            w=min(w,n);
            int ans=INF;
            REP(i,1,w+2) ans=min(ans,dis[t][i]);
            if(ans==INF)
                printf("No satisfactory flights\n");
            else
                printf("Total cost of flight(s) is $%d\n",ans);
        }
        if(T)
            printf("\n");
    }
    return 0;
}

  

时间: 2024-08-29 04:26:05

UVA-11280 Flying to Fredericton (dijkstra)的相关文章

UVA 11280 - Flying to Fredericton(最短路)

UVA 11280 - Flying to Fredericton 题目链接 题意:给定一些国家,和两个国家间的花费,现在有一些询问,询问每次最多转k次飞机,最小花费 思路:dijkstra变形,多开一维表示转机次数即可 代码: #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <iostream> #include <strin

UVa 12661 - Funny Car Racing(Dijkstra)

链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4399 题意: 在一个赛车比赛中,赛道有n(n≤300)个路口和m(m≤50000)条单向道路.有趣的是:每条路都是周期性关闭的.每条路用5个整数u, v, a, b, t表示(1≤u,v≤n,1≤a,b,t≤1e5),表示起点是u,终点是v,通过时间为t秒.另外,这条路会打开a秒,

UVA - 11280 Flying to Fredericton(SPFA)

题目大意:给出N个点,M条线,Q个询问,问从起点到终点,最多经过k个点的最短线路 解题思路:spfa直接跑,然后纪录最短路的数组加一个维度,纪录经过几个点就可以了,还是挺水的 #include <cstdio> #include <cstring> #include <map> #include <iostream> #include <queue> using namespace std; #define N 110 #define M 101

最短路径算法——迪杰斯特拉算法(Dijkstra)

图结构中应用的最多的就是最短路径的查找了,关于最短路径查找的算法主要有两种:迪杰斯特拉算法(Dijkstra)和Floyd算法. 其中迪杰斯特拉算法(Dijkstra)实现如下: 原理就是不断寻找当前的最优解: void main() { int V[Max][Max]={0,8,32,Infinity,Infinity, 12,0,16,15,Infinity, Infinity,29,0,Infinity,13, Infinity,21,Infinity,0,7, Infinity,Infi

hdu 1874(Dijkstra )

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1874 畅通工程续 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 27692    Accepted Submission(s): 10019 Problem Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路

Uva 10815-Andy&#39;s First Dictionary(串)

Problem B: Andy's First Dictionary Time limit: 3 seconds Andy, 8, has a dream - he wants to produce his very own dictionary. This is not an easy task for him, as the number of words that he knows is, well, not quite enough. Instead of thinking up all

UVA 10791 Minimum Sum LCM (数论)

LCM (Least Common Multiple) of a set of integers is defined as the minimum number, which is a multiple of all integers of that set. It is interesting to note that any positive integer can be expressed as the LCM of a set of positive integers. For exa

UVA 10375 Choose and divide(数论)

The binomial coefficient C(m,n) is defined as m! C(m,n) = -------- n!(m-n)! Given four natural numbers p, q, r, and s, compute the the result of dividing C(p,q) by C(r,s). The Input Input consists of a sequence of lines. Each line contains four non-n

uva:10700 - Camel trading(贪心)

题目:10700 - Camel trading 题目大意:给出一些表达式,表达式由数字和加号乘号组成,数字范围[1,20].这些表达式可能缺少了括号,问这样的表达式加上括号后能得到的最大值和最小值. 解题思路:因为这些数的都是正整数,所以可以用贪心.不然看出最大值就是先做完加法在做乘法,最小值就是先做乘法在做加法.注意这里的数值要用long long 因为比表达式的值可能会超过int. 代码: #include <stdio.h> #include <string.h> cons