首页 > 代码库 > codevs 1332 上白泽慧音
codevs 1332 上白泽慧音
题目链接:http://codevs.cn/problem/1021/
题解:
哦!最小值的最大值!!二分!!!……咳咳……
SPFA算法,邻接表(邻接矩阵应该不会炸,懒得试了……)
先进行一遍SPFA,用pre数组记录1到n的最短路径,之后枚举这条路径上的每一条边为“堵车”的路,删除该边并进行SPFA,每次进行完与当前ans比较,取较大值
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 #define MAXN 101000 6 #define MAXM 3010000 7 #define INF 214748364//注意,太大了会炸…… 8 int n,m,cnt,d[MAXN],heads[MAXN],q[MAXN],head,tail,pre[MAXN],ans,x,y,z; 9 bool viss[MAXN];10 struct node11 {12 int u,v;13 int next;14 int val;15 }edge[MAXM];16 void add(int x,int y,int z)17 {18 edge[++cnt].u=x;19 edge[cnt].v=y;20 edge[cnt].next=heads[x];21 edge[cnt].val=z;22 heads[x]=cnt;23 }24 void SPFA(bool _)//_值为true时进行的是第一遍SPFA,需要记录最短路径25 {26 head=1;tail=2;27 q[1]=1;28 viss[1]=true;29 while(head<tail)30 {31 for(int i=heads[q[head]];i!=0;i=edge[i].next)32 {33 if(d[q[head]]+edge[i].val<d[edge[i].v])34 {35 d[edge[i].v]=d[q[head]]+edge[i].val;36 if(_)pre[edge[i].v]=i;//记录最短路径,pre存储边的序号37 if(!viss[edge[i].v])38 {39 q[tail++]=edge[i].v;40 viss[edge[i].v]=true;41 }42 }43 }44 viss[q[head]]=false;45 head++;46 }47 }48 void __()//枚举最短路径上的每一条边49 {50 if(x%2)y=x+1;51 else y=x-1;//相邻两条单向边记录一条双向边,x,y分别记录两条边的编号52 z=edge[x].val;53 edge[x].val=edge[y].val=INF;//设置边权为很大的值相当于删除边54 for(int i=1;i<=n;i++)d[i]=INF;55 memset(viss,false,sizeof(viss));56 d[1]=0;57 memset(q,0,sizeof(q));58 SPFA(0);59 edge[x].val=edge[y].val=z;60 if(d[n]!=INF)ans=max(d[n],ans);61 x=pre[edge[x].u];//枚举下一条边62 if(x==0)return;63 __();64 }65 int main()66 {67 scanf("%d%d",&n,&m);68 for(int i=2;i<=n;i++)d[i]=INF;69 for(int i=1;i<=m;i++)70 {71 scanf("%d%d%d",&x,&y,&z);72 add(x,y,z);73 add(y,x,z);74 }75 SPFA(1);76 ans=max(ans,d[n]);//其实可以删掉77 x=pre[n];78 __();79 printf("%d",ans);80 return 0;81 }
PS:坑爹的codevs……,数据范围不准确,数组没开够竟然还显示TLE,把程序从递归改到循环之后才从zsc那里了解到这个问题……
循环程序可读性差,放递归程序
codevs 1332 上白泽慧音
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。