麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复。
因为她和他们不住在同一个城市,因此她开始准备她的长途旅行。
在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间。
麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路。无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市。
玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车。麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多长时间,这样他就能保证他的女朋友离开该城市足够远。
编写程序,帮助麦克找出玛丽卡按最短路线通过不堵车道路到达他所在城市所需的最长时间(用分钟表示)。
输入输出格式
输入格式:
第一行有两个用空格隔开的数N和M,分别表示城市的数量以及城市间道路的数量。1≤N≤1000,1≤M≤N 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到n)删除后再跑一遍最短路
如果所有的最短路上的变都枚举删一遍的话,会超时
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 const int maxn=5007; 9 const int INF=0x7f7f7f7f; 10 int n,m,num,stp,ans,head[maxn],d[maxn],st[maxn]; 11 queue<int>q; 12 int vis[maxn],poi[maxn]; 13 bool inq[maxn]; 14 struct Edge{ 15 int next,from,to,dis; 16 }edge[maxn*maxn]; 17 void add(int from,int to,int dis){ 18 edge[++num].next=head[from]; 19 edge[num].from=from; 20 edge[num].to=to; 21 edge[num].dis=dis; 22 head[from]=num; 23 } 24 bool bfs(int x){ 25 while(!q.empty()) q.pop(); 26 memset(poi,false,sizeof(poi)); 27 memset(vis,0,sizeof(vis)); 28 q.push(x); 29 while(!q.empty()){ 30 int u=q.front();q.pop(); 31 for(int i=head[u];i;i=edge[i].next){ 32 int v=edge[i].to; 33 if(d[v]==d[u]+edge[i].dis){ 34 if(poi[v]) vis[i]=2,poi[v]=2; 35 else vis[i]=1,poi[v]=1,q.push(v); 36 } 37 } 38 } 39 } 40 void spfa(int x){ 41 while(!q.empty()) q.pop(); 42 memset(d,INF,sizeof(d)); 43 memset(inq,false,sizeof(inq)); 44 d[x]=0;inq[x]=true;q.push(x); 45 while(!q.empty()){ 46 int u=q.front();q.pop();inq[u]=false; 47 for(int i=head[u];i;i=edge[i].next){ 48 int v=edge[i].to; 49 if(d[v]>d[u]+edge[i].dis){ 50 d[v]=d[u]+edge[i].dis; 51 if(!inq[v]){ 52 inq[v]=true;q.push(v); 53 } 54 } 55 } 56 } 57 bfs(1); 58 for(int i=1;i<=num;i++){ 59 if(vis[i]==1&&poi[edge[i].to]==true) st[++stp]=i; 60 } 61 } 62 int spfa2(int x){ 63 while(!q.empty()) q.pop(); 64 memset(d,INF,sizeof(d)); 65 memset(inq,false,sizeof(inq)); 66 d[1]=0;inq[1]=true;q.push(1); 67 while(!q.empty()){ 68 int u=q.front();q.pop();inq[u]=false; 69 for(int i=head[u];i;i=edge[i].next){ 70 if(i==x) continue; 71 int v=edge[i].to; 72 if(d[v]>d[u]+edge[i].dis){ 73 d[v]=d[u]+edge[i].dis; 74 if(!inq[v]){ 75 inq[v]=true;q.push(v); 76 } 77 } 78 } 79 } 80 return d[n]; 81 } 82 int main(){ 83 cin>>n>>m; 84 for(int i=1;i<=m;i++){ 85 int u,v,w;cin>>u>>v>>w; 86 add(u,v,w);add(v,u,w); 87 } 88 spfa(1); 89 for(int i=1;i<=stp;i++){ 90 ans=max(ans,spfa2(st[i])); 91 } 92 cout<<ans<<endl; 93 return 0; 94 }
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 const int maxn=5007; 9 const int INF=0x7f7f7f7f; 10 int n,m,num,stp,ans,head[maxn],d[maxn],st[maxn]; 11 queue<int>q; 12 int poi[maxn],ind[maxn]; 13 bool vis[maxn],inq[maxn]; 14 struct Edge{ 15 int next,from,to,dis; 16 }edge[maxn*maxn]; 17 void add(int from,int to,int dis){ 18 edge[++num].next=head[from]; 19 edge[num].from=from; 20 edge[num].to=to; 21 edge[num].dis=dis; 22 head[from]=num; 23 } 24 bool dfs(int x,int pre){ 25 if(x==n){ 26 if(poi[x]) poi[x]=2; 27 else poi[x]=1; 28 return true; 29 } 30 if(ind[x]==1) return false; 31 for(int i=head[x];i;i=edge[i].next){ 32 int v=edge[i].to;if(v==pre) continue; 33 if(d[v]==d[x]+edge[i].dis){ 34 if(poi[v]) poi[v]=2; 35 else poi[v]=1; 36 if(dfs(v,x)) vis[i]=true; 37 } 38 } 39 } 40 void spfa(){ 41 while(!q.empty()) q.pop(); 42 memset(d,INF,sizeof(d)); 43 memset(inq,false,sizeof(inq)); 44 d[1]=0;inq[1]=true;q.push(1); 45 while(!q.empty()){ 46 int u=q.front();q.pop();inq[u]=false; 47 for(int i=head[u];i;i=edge[i].next){ 48 int v=edge[i].to; 49 if(d[v]>d[u]+edge[i].dis){ 50 d[v]=d[u]+edge[i].dis; 51 if(!inq[v]){ 52 inq[v]=true;q.push(v); 53 } 54 } 55 } 56 } 57 dfs(1,0); 58 for(int i=1;i<=num;i++){ 59 if(vis[i]) st[++stp]=i; 60 } 61 } 62 int spfa2(int x){ 63 while(!q.empty()) q.pop(); 64 memset(d,INF,sizeof(d)); 65 memset(inq,false,sizeof(inq)); 66 d[1]=0;inq[1]=true;q.push(1); 67 while(!q.empty()){ 68 int u=q.front();q.pop();inq[u]=false; 69 for(int i=head[u];i;i=edge[i].next){ 70 if(i==x) continue; 71 int v=edge[i].to; 72 if(d[v]>d[u]+edge[i].dis){ 73 d[v]=d[u]+edge[i].dis; 74 if(!inq[v]){ 75 inq[v]=true;q.push(v); 76 } 77 } 78 } 79 } 80 return d[n]; 81 } 82 int main(){ 83 cin>>n>>m; 84 for(int i=1;i<=m;i++){ 85 int u,v,w;cin>>u>>v>>w; 86 add(u,v,w);add(v,u,w); 87 ind[u]++;ind[v]++; 88 } 89 spfa(); 90 for(int i=1;i<=stp;i++){ 91 ans=max(ans,spfa2(st[i])); 92 } 93 cout<<ans<<endl; 94 return 0; 95 }
这样会超时,因为会搜许多无用的边,然后还会WA??????
有好写,又快的题解是这样的
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<queue> 7 using namespace std; 8 const int maxn=5007; 9 const int INF=0x7f7f7f7f; 10 int n,m,num,ans; 11 int head[maxn],d[maxn],fa[maxn]; 12 bool inq[maxn],map[maxn][maxn],flag; 13 queue<int>q; 14 struct Edge{ 15 int next,to,dis; 16 }edge[maxn*maxn*2]; 17 void add(int from,int to,int dis){ 18 edge[++num].next=head[from]; 19 edge[num].to=to; 20 edge[num].dis=dis; 21 head[from]=num; 22 } 23 int spfa(){ 24 while(!q.empty()) q.pop(); 25 memset(d,INF,sizeof(d)); 26 memset(inq,false,sizeof(inq)); 27 d[1]=0;inq[1]=true;q.push(1); 28 while(!q.empty()){ 29 int u=q.front();q.pop();inq[u]=false; 30 for(int i=head[u];i;i=edge[i].next){ 31 int v=edge[i].to;if(map[u][v]) continue; 32 if(d[v]>d[u]+edge[i].dis){ 33 d[v]=d[u]+edge[i].dis; 34 if(!flag) fa[v]=u; 35 if(!inq[v]){ 36 inq[v]=true;q.push(v); 37 } 38 } 39 } 40 } 41 return d[n]; 42 } 43 int main(){ 44 cin>>n>>m; 45 for(int i=1;i<=m;i++){ 46 int u,v,w;cin>>u>>v>>w; 47 add(u,v,w);add(v,u,w); 48 } 49 spfa();flag=true; 50 for(int i=n;i!=1;i=fa[i]){ 51 map[i][fa[i]]=true; 52 map[fa[i]][i]=true; 53 ans=max(ans,spfa()); 54 map[i][fa[i]]=false; 55 map[fa[i]][i]=false; 56 } 57 cout<<ans<<endl; 58 return 0; 59 }
即使有多条相同的最短路也没有关系,反正这样找一定能找到一条