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
",++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
");
            else
                printf("Total cost of flight(s) is $%d
",ans);
        }
        if(T)
            printf("
");
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/20143605--pcx/p/4926594.html