CQNK圖論 1

thelittle_black發表於2020-12-21

達喀爾拉力賽
何老闆在今年的達喀爾汽車拉力賽中表現出色。現在還剩下最後一站的比賽,地圖上總共有n(不超過500)個城市,最後一站的起點是1號城市,終點是n號城市。這些城市間有m(不超過10000)條道路相連線。何老闆估計:因為是最後一站,所以選手們一定會選最近的道路行駛,所以這些道路上一定非常容易堵車。所以何老闆決定選從起點到終點的第二短的道路行駛。問:第二短的道路是多長?

何老闆選擇的第二短的路徑中,可以包含任何一條在最短路中出現的道路,並且,一條路可以重複走多次。當然咯,第二短路的長度必須嚴格大於最短路(可能有多條)的長度,但它的長度必須不大於所有除最短路外的路徑的長度。

樣例輸入
4 4
1 2 100
2 4 200
2 3 250
3 4 100

樣例輸出
450

看上去很高大上,實際上就是次短路

#include <bits/stdc++.h>
#define maxn 501
#define maxm 20001
#define INF 0x3f3f3f3f
using namespace std;
struct edge{
	int end,next,len;
};
edge maps[maxm]; //2是為了判斷最短路和次短路
int n,m,last[maxn],dis[maxn][2]; 
bool mark[maxn][2];//是否使用該節點
void dijkstra(int s)//圖論標準演算法之一
{
     int i,j,k,t,y,z,Min;
     for(i=1;i<=n;i++)
     {
         dis[i][0]=dis[i][1]=INF;
         mark[i][0]=mark[i][1]=false;
     }
     dis[s][0]=0;
     do
     {
         k=0; Min=INF;
         for(i=1;i<=n;i++)
         {
             if(!mark[i][0]&&dis[i][0]<Min)
             {
                 Min=dis[i][0];
                 k=i;  t=0;
             }
             else if(!mark[i][1]&&dis[i][1]<Min)
             {
                  Min=dis[i][1];
                  k=i; t=1;
             }
         }
         if(k>0)
         {
             mark[k][t]=true;//已經遍歷至該點
             j=last[k];
             while(j!=0)
             {
                  y=maps[j].end; z=maps[j].len;
                  if(Min+z<dis[y][0])
                  {
                      dis[y][1]=dis[y][0]; 
                      dis[y][0]=Min+z;
                  }
                  else if((Min+z<dis[y][1])&&(Min+z>dis[y][0]))dis[y][1]=Min+z;
                  j=maps[j].next;
             }
         }
     }while(k>0);                
}
int main()
{
    int i,x,y,z;
    scanf("%d%d",&n,&m);
    for(i=1;i<=m;i++){
        scanf("%d%d%d",&x,&y,&z);//用二維陣列容易超時
        maps[i].end=y;  maps[i].len=z;  maps[i].next=last[x]; last[x]=i;
        maps[i+m].end=x; maps[i+m].len=z; maps[i+m].next=last[y]; last[y]=i+m;   
    }
    dijkstra(1);//開始遍歷
    printf("%d",dis[n][1]);//1是次短路
    //最短路就是0
    return 0;
}

相關文章