南华大学第十五届ACM程序设计竞赛(重现赛) E 免费机票

链接:https://ac.nowcoder.com/acm/contest/699/E
来源:牛客网
 

题目描述

        某华大学小飞中奖了!!!奖品是一张免费飞机票,唯一遗憾的是,这张飞机票有限定区间,需要从k个区间中选择其一。小飞打算高高兴兴的出去玩啦,但是,从s地出发,去往e地,可能没有直达的飞机票,可能需要转机(所有飞机线路都是无向的),小飞毕竟是个学生党,出去玩首先得考虑省钱,所以,小飞遇到麻烦了,请帮小飞计算最便宜的一条路线,小飞会很感激你的。

输入描述:

第一行为三个整数n,s,e,n表示n个不同城市的飞机场,s为出发点,e为目的地。(1<=n<=1000,  1<=s,e<=n)

第二行为一个整数m,表示m条普通飞机线路,接下来的m行描述每条线路,每行包含三个整数a、b、c,a、b代表普通飞机线路两端,c表示价格。(1<=m<=1000,  1<=a,b<=n,  1<=c<=1000)

接下来的一行为一个整数k,表示k个免费机票的航线区间, 然后k行来描述每条免费航线,每行两个整数a’、b’,    分别代表免费航线两端。(1<=k<=1000,  1<=a’,b’<=n)

输出描述:

每个测试数据有两行输出,第一行为是否使用免费飞机票,是则输出“Yes”,否则输出“No”。第二行输出总共花费。

示例1

输入

复制

4 1 4
3
1 2 1
1 3 2
2 4 3
1
3 4

输出

复制

Yes
2

示例2

输入

复制

7 1 7
5
1 4 1
1 5 2
1 7 10
4 7 8
5 7 5
2
2 4
6 7

输出

复制

No
7

我的思路很简单,就是建完图之后跑一次最短路,然后再分别跑k次,对比一下就行了

有个地方要注意的是,在你加过一次免费边 跑完dijk的时候,要把这个边删掉,再加剩下的

因为题目要求只能选k中的一条

代码写的比较丑。。。

 

#include 
using namespace std;
typedef long long ll;
const int maxn=1e4+5;
const int maxm=1e4+5;
int head[maxn],vis[maxn],cnt,n,m,s,ee;
ll dis[maxn];
struct edge
{
    int to,next,dis;
}e[maxm];
void addedge(int u,int v,int w)
{
    cnt++;
    e[cnt].to=v;
    e[cnt].dis=w;
    e[cnt].next=head[u];
    head[u]=cnt;
}
struct node
{
    int pos;ll dis;
    bool operator <(const node &x)const
    {
        return x.disq;
inline void dijkstra()
{
    for(int i=1;i<=n;i++) dis[i]=0x3f3f3f3f;
    dis[s]=0;
    q.push((node){s,0});
    while(!q.empty())
    {
        node tmp=q.top();
        q.pop();
        int x=tmp.pos;
        if(vis[x]) continue;
        vis[x]=1;
        for(int i=head[x];i;i=e[i].next)
        {
            int y=e[i].to;
            if(dis[y]>dis[x]+e[i].dis)
            {
                dis[y]=dis[x]+e[i].dis;
                if(!vis[y])
                 
                    q.push((node){y,dis[y]});
                 
            }
        }
    }
}
int uu[maxn],vv[maxn],ww[maxn]; int cntt;
int main()
{
    scanf("%d%d%d%d",&n,&s,&ee,&m);
    for(int i=0;i

 

你可能感兴趣的:(牛客网,最短路)