luogu P1186玛丽卡

题目描述

麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复。

因为她和他们不住在同一个城市,因此她开始准备她的长途旅行。

在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间。

麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路。无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市。

玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车。麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多长时间,这样他就能保证他的女朋友离开该城市足够远。

编写程序,帮助麦克找出玛丽卡按最短路线通过不堵车道路到达他所在城市所需的最长时间(用分钟表示)。

输入输出格式

输入格式:

第一行有两个用空格隔开的数N和M,分别表示城市的数量以及城市间道路的数量。1≤N≤1000,1≤M≤N*(N-1)/2。城市用数字1至N标识,麦克在城市1中,玛丽卡在城市N中。

接下来的M行中每行包含三个用空格隔开的数A,B和V。其中1≤A,B≤N,1≤V≤1000。这些数字表示在A和城市B中间有一条双行道,并且在V分钟内是就能通过。

输出格式:

输出文件的第一行中写出用分钟表示的最长时间,在这段时间中,无论哪条路在堵车,玛丽卡应该能够到达麦克处,如果少于这个时间的话,则必定存在一条路,该条路一旦堵车,玛丽卡就不能够赶到麦克处。

输入输出样例

输入样例#1:

5 7
1 2 8
1 4 10
2 3 9
2 4 10
2 5 1
3 4 7
3 5 10

输出样例#1:

27直接暴力枚举每条边不能走取最小(TLE5):
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<queue>
 5
 6 using namespace std;
 7 const int N=1010;
 8 const int Maxn=99999999;
 9
10 int head[N];
11 int dis[N];
12 bool vis[N];
13 int now=1;
14 queue<int>q;
15 int n,m;
16 int x,y;
17
18 struct node{
19     int u,v,w,nxt;
20 }E[N*(N-1)/2];
21
22 inline int read()
23 {
24     int x=0;
25     char c=getchar();
26     while(c<‘0‘||c>‘9‘)c=getchar();
27     while(c>=‘0‘&&c<=‘9‘)x=x*10+c-‘0‘,c=getchar();
28     return x;
29 }
30
31 inline void add(int u,int v,int w)
32 {
33     E[now].u=u;
34     E[now].v=v;
35     E[now].w=w;
36     E[now].nxt=head[u];
37     head[u]=now++;
38 }
39
40 inline void spfa(int start)
41 {
42     for(int i=1;i<=n;i++)
43         dis[i]=Maxn;
44     dis[start]=0;
45     vis[start]=1;
46     q.push(start);
47     while(!q.empty())
48     {
49         int top=q.front();
50         q.pop();
51         vis[top]=0;
52         for(int i=head[top];i!=-1;i=E[i].nxt)
53         {
54             int u=E[i].u,v=E[i].v;
55             if((u!=x&&u!=y)||(v!=x&&v!=y))
56                 if(dis[v]>dis[u]+E[i].w)
57                 {
58                     dis[v]=dis[u]+E[i].w;
59                     if(!vis[v])
60                     {
61                         vis[v]=1;
62                         q.push(v);
63                     }
64                 }
65         }
66     }
67 }
68
69 int main()
70 {
71     n=read();
72     m=read();
73     for(int i=1;i<=n;i++)
74         head[i]=-1;
75     for(int i=1;i<=m;i++)
76     {
77         int u=read(),v=read(),w=read();
78         add(u,v,w);
79         add(v,u,w);
80     }
81     int answer=-1;
82     for(int i=1;i<=2*m;i++)
83     {
84         x=E[i].u;
85         y=E[i].v;
86         spfa(1);
87         answer=max(answer,dis[n]);
88     }
89     printf("%d",answer);
90     return 0;
91 }

后来通过画图发现,上述方法多枚举了较多条无用边,可以先求出最短路,枚举每一条最短路上的边:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<queue>
  5
  6 using namespace std;
  7 const int N=1010;
  8 const int Maxn=99999999;
  9
 10 int head[N];
 11 int dis[N];
 12 bool vis[N];
 13 int fa[N];
 14 int now=1;
 15 queue<int>q;
 16 int n,m;
 17 int x,y;
 18
 19 struct node{
 20     int u,v,w,nxt;
 21 }E[N*(N-1)];
 22
 23 inline int read()
 24 {
 25     int x=0;
 26     char c=getchar();
 27     while(c<‘0‘||c>‘9‘)c=getchar();
 28     while(c>=‘0‘&&c<=‘9‘)x=x*10+c-‘0‘,c=getchar();
 29     return x;
 30 }
 31
 32 inline void add(int u,int v,int w)
 33 {
 34     E[now].u=u;
 35     E[now].v=v;
 36     E[now].w=w;
 37     E[now].nxt=head[u];
 38     head[u]=now++;
 39 }
 40
 41 inline void spfa_1(int start)
 42 {
 43     for(int i=1;i<=n;i++)
 44         dis[i]=Maxn;
 45     dis[start]=0;
 46     vis[start]=1;
 47     q.push(start);
 48     while(!q.empty())
 49     {
 50         int top=q.front();
 51         q.pop();
 52         vis[top]=0;
 53         for(int i=head[top];i!=-1;i=E[i].nxt)
 54         {
 55             if(dis[E[i].v]>dis[E[i].u]+E[i].w)
 56             {
 57                 dis[E[i].v]=dis[E[i].u]+E[i].w;
 58                 fa[E[i].v]=E[i].u;
 59                 if(!vis[E[i].v])
 60                 {
 61                     vis[E[i].v]=1;
 62                     q.push(E[i].v);
 63                 }
 64             }
 65         }
 66     }
 67 }
 68
 69 inline void spfa_2(int start)
 70 {
 71     for(int i=1;i<=n;i++)
 72         dis[i]=Maxn,vis[i]=0;
 73     dis[start]=0;
 74     vis[start]=1;
 75     q.push(start);
 76     while(!q.empty())
 77     {
 78         int top=q.front();
 79         q.pop();
 80         vis[top]=0;
 81         for(int i=head[top];i!=-1;i=E[i].nxt)
 82         {
 83             int u=E[i].u,v=E[i].v;
 84             if((u!=x&&u!=y)||(v!=x&&v!=y))
 85                 if(dis[v]>dis[u]+E[i].w)
 86                 {
 87                     dis[v]=dis[u]+E[i].w;
 88                     if(!vis[v])
 89                     {
 90                         vis[v]=1;
 91                         q.push(v);
 92                     }
 93                 }
 94         }
 95     }
 96 }
 97
 98 int main()
 99 {
100     n=read();
101     m=read();
102
103     for(int i=1;i<=n;i++)
104         head[i]=-1;
105     for(int i=1;i<=m;i++)
106     {
107         int u=read(),v=read(),w=read();
108         add(u,v,w);
109         add(v,u,w);
110     }
111
112     spfa_1(1);
113     int answer=-1;
114     int i=n;
115     while(fa[i]>=1)
116     {
117         x=i;
118         y=fa[i];
119         spfa_2(1);
120         answer=max(answer,dis[n]);
121         i=fa[i];
122     }
123     printf("%d",answer);
124     return 0;
125 }
时间: 2024-10-13 09:30:51

luogu P1186玛丽卡的相关文章

luogu P1186 玛丽卡

题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间. 麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路.无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市. 玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车.麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多长时间,这样他就能保

Luogu P1186 玛丽卡 【最短路】By cellur925

题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间. 麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路.无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市. 玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车.麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多长时间,这样他就能保

【luogu P1186 玛丽卡】 题解

题目链接:https://www.luogu.org/problemnew/show/P1186 邻接表开大开小真的奇妙,毒瘤玩意,再您妈的见. #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1010; const int inf

P1186 玛丽卡

P1186 玛丽卡 题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间. 麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路.无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市. 玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车.麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多

P2176路障与P1186玛丽卡与P1491集合位置全面胜利

P2176 [USACO14FEB]路障Roadblock P1186 玛丽卡 P1491 集合位置 怎么又做到三倍经验,五年计划都超额完成了 这几道题像极了. 想起来不难吧,要让边改变之后与原来的最短路差值最大,就把最短路上的边改了呗. 用一个队列来记录最短路上的边,然后枚举这个队列里的元素,依次改变,刷出最大值. 代码有点不好写,这次我加上注释了. 不要问我为什么变量名怎么这么长,最近沉迷代码补全. P2176的代码: #include<bits/stdc++.h> using names

洛谷 P1186 玛丽卡

题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间. 麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路.无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市. 玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车.麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多长时间,这样他就能保

洛谷P1186 玛丽卡

题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间. 麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路.无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市. 玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车.麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多长时间,这样他就能保

P1186 玛丽卡 --- 最短路

-> 题意:有n个点,m条无向边,问从1到n(或从n到1)的一个最长时间t,且满足删除任意一条边后,得到的最短路都小于等于这个时间t. 思路:可以发现只有删除最短路上的边时才会对答案有影响.因此我们枚举最短路上的每一条边,将它们删去后跑最短路,最后取max即为答案.注意删边后图要保证连通. 代码: 60pt:枚举每条边 #include<cstdio> #include<cstring> #include<algorithm> #include<queue&

luoguP1186 玛丽卡 x

P1186 玛丽卡 题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间. 麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路.无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市. 玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车.麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多