首页 > 代码库 > luogu P1186玛丽卡
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 }
luogu P1186玛丽卡
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。