携程 最短路径的代价

携程的一道图论题

题意:给出一张无向图 每条边有一个长度和 删除该边的权值  再给出起点和终点 求从起点到终点的最短路增加 要删除的边的最小的权值和。

【思路】要使 从起点到终点的最短路长度增加 就要把该最短路破坏掉  从起点到终点的最短路可能不止一条,我们可以把 这些路径都找出来 重新构成一个图

            再求这个图的最小割 就是答案了    怎么把这些路径都找出来呢  求两次最短路 第一次求 所有点到起点的最短路d1[x]  第二次求所有点到终点的最短               路 d2[x]    从起点到终点的最短路为ans 。再遍历每一条边 对于d1[u]+d2[v]+w[u][v]== ans 的边就可以加入了~

    

 

还要改一点 先放这里

 

 

  1 #include<iostream>
  2 #include<stdio.h>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<queue>
  6 #include<math.h>
  7 #include<algorithm>
  8 #include<vector>
  9 #define maxx 9999999
 10 using namespace std;
 11 
 12 struct E{int from;int to;int c;int f;};
 13 struct node{int v;int w;int c;};
 14 vector <node> g1[1002];
 15 vector <int > g[1002];
 16 vector<E> edge;
 17 int vis[1002],d1[1002],d2[1002],n,a[1002],p[1002],num[1002],cur[1002],d[1002];
 18 
 19 void add(int from,int to,int c)
 20  {
 21      E temp1,temp2;
 22      temp1.from =from; temp1.to=to; temp1.c=c;temp1.f=0;
 23      temp2.from =to; temp2.to=from; temp2.c=0;temp2.f=0;
 24      edge.push_back (temp1);
 25      edge.push_back (temp2);
 26      int m=edge.size ();
 27      g[from].push_back (m-2);
 28      g[to].push_back (m-1);
 29  }
 30 
 31  void bfs(int s,int t)
 32  {
 33      int i;
 34      queue<int > q;
 35      q.push (t);
 36      d[t]=0;
 37      memset(vis,0,sizeof(vis));
 38      vis[t]=1;
 39      while(!q.empty ())
 40      {
 41          int t=q.front ();q.pop ();
 42          for(i=0;i<g[t].size ();i++)
 43          {
 44             E e;e=edge[g[t][i]];
 45             if(!vis[e.to])
 46             {
 47                 q.push (e.to);
 48                 vis[e.to]=1;
 49                 d[e.to]=d[t]+1;
 50             }
 51          }
 52      }
 53  }
 54 
 55  int zg(int s,int t)
 56  {
 57      int x=t,a=maxx;
 58      while(x!=s)
 59      {
 60          //printf("x   %d\n",x);
 61          E e=edge[p[x]];
 62          if(a>e.c-e.f)
 63              a=e.c-e.f;
 64          x=e.from;
 65      }
 66      x=t;
 67      while(x!=s)
 68      {
 69          edge[p[x]].f+=a;
 70          edge[p[x]^1].f-=a;
 71          x=edge[p[x]].from ;
 72      }
 73      return a;
 74  }
 75 
 76  int maxflow(int s,int t,int n)
 77  {
 78      int flow=0,i;
 79      bfs(s,t);
 80      memset(num,0,sizeof(num));
 81      memset(cur,0,sizeof(cur));
 82      for(i=0;i<=t;i++)
 83          num[d[i]]++;
 84      int x=s;
 85      while(d[s]<n)
 86      {
 87          if(x==t)
 88          {
 89              flow+=zg(s,t);
 90              x=s;
 91              printf("flow  %d\n",flow);
 92          }
 93          int ok=0;
 94          for(i=cur[x];i<g[x].size ();i++)
 95          {
 96              E e;
 97              e=edge[g[x][i]];
 98              if(e.c>e.f&&d[x]==d[e.to]+1)
 99              {
100                  ok=1;
101 
102                  p[e.to]=g[x][i];
103 
104                  cur[x]=i;
105                  x=e.to;//!@#$%^&
106                  break;
107              }
108          }
109          if(ok==0)
110          {
111              int m=n;
112              for(i=0;i<g[x].size ();i++)
113              {
114                  E e;
115                  e=edge[g[x][i]];
116                  if(e.c>e.f&&m>d[e.to])
117                      m=d[e.to];
118              }
119              if(--num[d[x]]==0)  break;
120              num[d[x]=m+1]++;
121              cur[x]=0;////!@#$%^^&
122              if(x!=s)
123                  x=edge[p[x]].from ;
124 
125          }
126      }
127      return flow;
128  }
129 
130 
131 int spfa1(int s,int t)
132 {
133     queue<int > q;
134     memset(vis,0,sizeof(vis));
135     for(int i=0;i<=n;i++)
136         d1[i]=maxx;
137     d1[s]=0;
138     vis[s]=1;
139     q.push(s);
140     while(!q.empty())
141     {
142         int u;
143         u=q.front(); q.pop(); vis[u]=0;
144         for(int i=0;i<g1[u].size();i++)
145         {
146             int v;
147             v=g1[u][i].v;
148             if((d1[u]+g1[u][i].w)<d1[v])
149             {
150                 d1[v]=d1[u]+g1[u][i].w;
151                 if(!vis[v])
152                 {
153                     vis[v]=1;
154                     q.push(v);
155                 }
156             }
157         }
158     }
159     return d1[t];
160 }
161 int spfa2(int s,int t)
162 {
163     queue<int > q;
164     memset(vis,0,sizeof(vis));
165     for(int i=0;i<=n;i++)
166         d2[i]=maxx;
167     d2[s]=0;
168     vis[s]=1;
169     q.push(s);
170     while(!q.empty())
171     {
172         int u;
173         u=q.front(); q.pop(); vis[u]=0;
174         for(int i=0;i<g1[u].size();i++)
175         {
176             int v;
177             v=g1[u][i].v;
178             if((d2[u]+g1[u][i].w)<d2[v])
179             {
180                 d2[v]=d2[u]+g1[u][i].w;
181                 if(!vis[v])
182                 {
183                     vis[v]=1;
184                     q.push(v);
185                 }
186             }
187         }
188     }
189     return d2[t];
190 }
191 
192 
193 int main()
194 {
195     int m,i,j,a,b,s,t,t1,t2;
196     while(~scanf("%d%d",&n,&m))
197     {
198         if(n==0&&m==0)
199             break;
200         scanf("%d%d",&s,&t);
201         for(i=0;i<=n;i++)
202         {
203             g[i].clear();
204             g1[i].clear();
205         }
206         edge.clear();
207         while(m--)
208         {
209             scanf("%d%d%d%d",&a,&b,&t1,&t2);
210             node temp;
211             temp.v=b; temp.c=t2; temp.w=t1;
212             g1[a].push_back(temp);
213             temp.v=a;
214             g1[b].push_back(temp);
215 
216         }
217        int ans;
218        ans=spfa1(s,t);
219        spfa2(t,s);
220        //printf("chang   %d\n",ans);
221        for(int i=1;i<=n;i++)  //构图 求最大流
222            for(int j=0;j<g1[i].size();j++)
223            {
224                int v;
225                v=g1[i][j].v;
226                //printf("%d %d %d %d %d\n",i,v,d1[i],d2[v],g[i][j].w);
227                if((d1[i]+d2[v]+g1[i][j].w)==ans||(d2[i]+d1[v]+g1[i][j].w)==ans)//
228                {
229                    //printf("iv  %d %d %d\n",i,v,g1[i][j].c);
230                    add(i,v,g1[i][j].c);////
231                }
232            }
233            //printf("***");
234            //printf("st  %d %d\n",s,t);
235            printf("ans     %d\n",maxflow(s,t,n));
236     }
237     return 0;
238 }

 

 

转载于:https://www.cnblogs.com/assult/p/3667223.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值