zoukankan      html  css  js  c++  java
  • HDU3986 SPFA

    题意:给定一张图,从1到n,若能随便去除一条路,问最短路?

    注意:两点可能存在多条路,这时 事实上只要保存下第一短和第二短的,然后在枚举的时候每次去除一条换上第二短的路。。。。。

    这样最后就能得到ans。

    (若存在某种方法使得1不能到n,则break,print -1 )

    View Code
      1 #include<stdio.h>
      2  #include<string.h>
      3  #include<stdlib.h>
      4  #include<queue>
      5  #include<algorithm>
      6  using namespace std;
      7  const int maxn = 1105;
      8  const int maxm = 110005;
      9  const int inf = 1000000000;
     10  struct node{
     11      int u,val,next;
     12  }edge[ maxm ];
     13  int head[ maxn ],cnt;
     14  int n;
     15  int dis[ maxn ],vis[ maxn ];
     16  struct node3{
     17      int u,val;
     18  }path[ maxn ];
     19  struct node2{
     20      int x,y,val;
     21  }road[ maxm ];
     22  void init(){
     23      cnt=0;
     24      memset( head,-1,sizeof( head ));
     25     // for( int i=1;i<=n;i++ )
     26         // for( int j=1;j<=n;j++ )
     27             // mat[i][j]=inf;
     28  }
     29  void addedge( int a,int b,int c ){
     30      edge[ cnt ].u=b;
     31      edge[ cnt ].val=c;
     32      edge[ cnt ].next=head[ a ];
     33      head[ a ]=cnt++;
     34  }
     35  void spfa( int s ){
     36      for( int i=1;i<=n;i++ ){
     37          dis[i]=inf;
     38          vis[i]=0;
     39          path[i].u=-1;
     40      }
     41      queue<int>q;
     42      while( !q.empty() )
     43          q.pop();
     44      vis[s]=1;
     45      dis[s]=0;
     46      q.push( s );
     47      while( !q.empty() ){
     48          int now=q.front();
     49          q.pop();
     50          vis[ now ]=0;
     51          for( int i=head[ now ];i!=-1;i=edge[i].next ){
     52              int next=edge[i].u;
     53              if( dis[next]>dis[now]+edge[i].val ){
     54                  dis[next]=dis[now]+edge[i].val;
     55                  path[next].u=now;
     56                  path[next].val=edge[i].val;
     57                  if( vis[next]==0 ){
     58                      vis[next]=1;
     59                      q.push(next);
     60                  }
     61              }
     62          }
     63      }
     64      return ;
     65  }
     66  void change( int pos,int x,int y,int pre,int nxt ){
     67      //int tmp_max=inf,k;
     68      for( int i=head[ x ];i!=-1;i=edge[ i ].next ){
     69          if( edge[i].u==y&&edge[i].val==pre ){
     70              edge[i].val=nxt;
     71              break;//注意这个break,如果某两个点之间存在两条相同长度的路径,这是只要改变其中一条即可!!!
     72          }
     73      }
     74 
     75  }
     76  int main(){
     77      int ca;
     78      scanf("%d",&ca);
     79      while( ca-- ){
     80          scanf("%d",&n);
     81          int m;
     82          scanf("%d",&m);
     83          int a,b,c;
     84          init();
     85          while( m-- ){
     86              scanf("%d%d%d",&a,&b,&c);
     87              addedge( a,b,c );
     88              addedge( b,a,c );
     89          }
     90          spfa( 1 );
     91          cnt=0;
     92          for( int i=n;i!=-1;i=path[i].u ){
     93              road[ cnt ].x=i;
     94              road[ cnt ].y=path[i].u;
     95              road[ cnt ].val=path[i].val;
     96              cnt++;
     97          }//先spfa出最短路的路径
     98          int ans=dis[n];
     99          if( ans==inf ){
    100              printf("-1\n");
    101              continue;
    102          }
    103          for( int i=0;i<cnt;i++ ){
    104              int pre=road[i].val;
    105              int nxt=inf;
    106              change( i,road[i].x,road[i].y,pre,nxt );
    107              change( i,road[i].y,road[i].x,pre,nxt );
    108              spfa(1);
    109              if( dis[n]==inf ){
    110                  ans=inf;
    111                  break;
    112              }
    113              if( dis[n]>ans&&dis[n]!=inf ){
    114                  ans=dis[n];
    115              }
    116              change( i,road[i].x,road[i].y,nxt,pre/*mat[road[i].x][road[i].y]*/ );
    117              change( i,road[i].y,road[i].x,nxt,pre/*mat[road[i].x][road[i].y]*/ );
    118              ////每次改变原最短路中的某一条,如果这两点之间存在多条路,则挑第二短的路再spfa即可!!!
    119          }
    120          if( ans==inf )
    121              printf("-1\n");
    122          else
    123              printf("%d\n",ans);
    124      }
    125      return 0;
    126  }
    keep moving...
  • 相关阅读:
    什么是前端开发工程师?
    JS(JavaScript)的深入了解1(更新中···)
    JS(JavaScript)的j进一步了解9(更新中···)
    JS(JavaScript)的进一步了解8(更新中···)
    JS(JavaScript)的进一步了解7(更新中···)
    JS(JavaScript)的进一步了解6(更新中···)
    JS(JavaScript)的进一步了解5(更新中···)
    JS(JavaScript)的进一步了解4(更新中···)
    JS(JavaScript)的进一步了解3(更新中···)
    React:react-router-dom 详解
  • 原文地址:https://www.cnblogs.com/xxx0624/p/2933534.html
Copyright © 2011-2022 走看看