P1186 玛丽卡 --- 最短路
Posted dprswdr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1186 玛丽卡 --- 最短路相关的知识,希望对你有一定的参考价值。
题意:有n个点,m条无向边,问从1到n(或从n到1)的一个最长时间t,且满足删除任意一条边后,得到的最短路都小于等于这个时间t。
思路:可以发现只有删除最短路上的边时才会对答案有影响。因此我们枚举最短路上的每一条边,将它们删去后跑最短路,最后取max即为答案。注意删边后图要保证连通。
代码:
60pt:枚举每条边
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int N=1000+100,M=500000+10; int n,m; struct node{ int to,nxt,w; }e[M<<1]; int head[N],tot=1; void add(int u,int v,int w){ e[++tot]=(node){v,head[u],w}; head[u]=tot; } queue<int>q; bool vis[N]; int dis[N]; int SPFA(int edge){ while(q.size()) q.pop(); for(int i=1;i<=n;i++) { vis[i]=false; dis[i]=(1<<30); } dis[1]=0,vis[1]=true; q.push(1); while(q.size()){ int u=q.front();q.pop();vis[u]=0; for(int i=head[u];i;i=e[i].nxt){ int v=e[i].to; if(dis[v]>dis[u]+e[i].w){ dis[v]=dis[u]+e[i].w; if(!vis[v]){ q.push(v);vis[v]=1; } } } } return dis[n]; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,w); } int ans=SPFA(tot+233); for(int i=1;i<=tot;i++){ int x=e[i].w; e[i].w=(1<<30); int now=SPFA(i); e[i].w=x; if(now!=(1<<30)) ans=max(ans,now); } printf("%d",ans); return 0; }
100pt:枚举最短路
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 using namespace std; 6 const int N=1000+100,M=500000+10; 7 int n,m; 8 struct node{ 9 int fro,to,nxt,w; 10 }e[M<<1]; 11 int head[N],tot=1; 12 void add(int u,int v,int w){ 13 e[++tot]=(node){u,v,head[u],w}; 14 head[u]=tot; 15 } 16 queue<int>q; 17 bool vis[N]; 18 int dis[N]; 19 int pre[N]; 20 //通过记录每个点的前驱来记录最短路路径 21 bool f; 22 //标记是否为第一次SPFA,即是否要记录前驱 23 void SPFA(){ 24 while(q.size()) q.pop(); 25 for(int i=1;i<=n;i++) { 26 vis[i]=false; 27 dis[i]=(1<<30); 28 //千万别像我把pre初始化了 29 } 30 dis[n]=0,vis[n]=true; 31 q.push(n); 32 while(q.size()){ 33 int u=q.front();q.pop();vis[u]=0; 34 for(int i=head[u];i;i=e[i].nxt){ 35 int v=e[i].to; 36 if(dis[v]>dis[u]+e[i].w){ 37 if(!f) 38 //因为要求最初的最短路路径 39 //所以只有第一次最短路时才记录每个点的前驱 40 pre[v]=i; 41 dis[v]=dis[u]+e[i].w; 42 if(!vis[v]){ 43 q.push(v);vis[v]=1; 44 } 45 } 46 } 47 } 48 } 49 int main() { 50 scanf("%d%d",&n,&m); 51 for(int i=1;i<=m;i++){ 52 int u,v,w; 53 scanf("%d%d%d",&u,&v,&w); 54 add(u,v,w); 55 add(v,u,w); 56 } 57 SPFA(); 58 f=true; 59 int ans=dis[1]; 60 for(int i=pre[1];i;i=pre[e[i].fro]){ 61 //枚举记录的最短路路径 62 int x=e[i].w; 63 e[i].w=(1<<30); 64 SPFA(); 65 e[i].w=x;//回溯 66 if(dis[1]!=(1<<30)) //图要保证连通 67 ans=max(ans,dis[1]); 68 } 69 printf("%d",ans); 70 return 0; 71 }
以上是关于P1186 玛丽卡 --- 最短路的主要内容,如果未能解决你的问题,请参考以下文章