P1491 集合位置 求次短路

题意:0.0

思路:我们把图建好之后,先跑一遍求出最短路路径,然后再枚举要删除的边

   要删除的边自然是最短路径上的边,因为假如不选最短路径上的边,权值是不会变化的

   所以,要想求次短路,我们就注意枚举最短边然后更新答案即可

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=1e3+10;
  4 const double inf=1000000000.0;
  5 double x[maxn],y[maxn];
  6 int match[maxn];
  7 int cut[maxn][maxn];
  8 double dis[maxn];
  9 int vis[maxn];
 10 int n,m;
 11 double cal(int t1,int t2)
 12 {
 13     return sqrt((x[t1]-x[t2])*(x[t1]-x[t2])+(y[t1]-y[t2])*(y[t1]-y[t2]));
 14 }
 15 struct node
 16 {
 17     int v,nxt;
 18     double w;
 19 }G[20010]; int head[20010]; int num;
 20 void add(int u,int v,double w)
 21 {
 22     G[++num].v=v;G[num].w=w;G[num].nxt=head[u];head[u]=num;
 23 }
 24 void SPFA1()
 25 {
 26     queue<int>q;
 27     for(int i=0;i<=n;i++){
 28         dis[i]=inf;
 29         vis[i]=0;
 30     }
 31     q.push(1);
 32     vis[1]=1;
 33     dis[1]=0.0;
 34     while(!q.empty()){
 35         int u=q.front();
 36         q.pop();
 37         vis[u]=0;
 38         for(int i=head[u];i;i=G[i].nxt){
 39             int v=G[i].v;
 40             double w=G[i].w;
 41             if(dis[v]>dis[u]+w){
 42                 dis[v]=dis[u]+w;
 43                 match[v]=u;
 44                 if(!vis[v]){
 45                     q.push(v);
 46                     vis[v]=1;
 47                 }
 48             }
 49         }
 50     }
 51 }
 52 void SPFA2()
 53 {
 54     queue<int>q;
 55     for(int i=0;i<=n;i++){
 56         dis[i]=inf;
 57         vis[i]=0;
 58     }
 59     q.push(1);
 60     vis[1]=1;
 61     dis[1]=0.0;
 62     while(!q.empty()){
 63         int u=q.front();
 64         q.pop();
 65         vis[u]=0;
 66         for(int i=head[u];i;i=G[i].nxt){
 67             int v=G[i].v;
 68             double w=G[i].w;
 69             if(cut[u][v]) continue;
 70             if(dis[v]>dis[u]+w){
 71                 dis[v]=dis[u]+w;
 72                 if(!vis[v]){
 73                     q.push(v);
 74                     vis[v]=1;
 75                 }
 76             }
 77         }
 78     }
 79 }
 80 int main()
 81 {
 82     scanf("%d%d",&n,&m);
 83     for(int i=1;i<=n;i++){
 84         scanf("%lf%lf",&x[i],&y[i]);
 85     }
 86     for(int i=1;i<=m;i++){
 87         int u,v;
 88         scanf("%d%d",&u,&v);
 89         double w=cal(u,v);
 90         add(u,v,w);
 91         add(v,u,w);
 92     }
 93     SPFA1();
 94     int now=n;
 95     double ans=inf;
 96     while(match[now]){
 97         int u=now;int v=match[now];
 98         cut[u][v]=cut[v][u]=1;
 99         SPFA2();
100         cut[u][v]=cut[v][u]=0;
101         ans=min(ans,dis[n]);
102         now=match[now];
103     }
104     if(ans>=inf) printf("-1\n");
105     else  printf("%.2f\n",ans);
106     return 0;
107 }
View Code

 

posted @ 2020-04-17 21:47  古比  阅读(172)  评论(0编辑  收藏  举报