最短路和次短路的結合,之前沒有碰到過次短路。為此自己特地把最短路知識又復習了一遍,然後看了其他人的想法,最後才寫了出來,具體來說,其實不太難,重點是理解思想。存儲的時候采用鄰接表。
解法:
用到的數組:dist[i][0]:i到起點的最短路,dist[i][1]:i到起點的嚴格次短路
visited[i][0],visited[i][1]:同一維的visited數組,標記距離是否已確定
sum[i][0]:i到起點的最短路條數,sum[i][1]:i到起點的次短路條數
同一維dijkstra,內循環先找出最短的距離(次短路或最短路)d,然後枚舉與該點相連的點:
if(d < 最小) 更新最小和次小,包括距離以及路徑條數
else if(d == 最小) 更新最短路徑條數
else if(d < 次小) 更新次小,包括次小距離路徑條數
else if(d == 次小) 更新次小路徑條數
從這題自己也學到了一點東西:
之前寫最短路的題目時,總是在求最短路的距離,沒有碰到求最短路有幾條的。那麼只有把這題稍微修改一下不就可以求解最短路徑有幾條了嗎?而且再把這題的算法稍微修改一下不就可以求次短路了嗎?
#include#include #include #include #include #include using namespace std; const int inf=1<<28; const int N=1005; const int M=10005;www.2cto.com int dist[N][2],sum[N][2],head[N]; bool visited[N][2]; struct Edge { int v,w; int next; }edge[M]; int top,s,e,n,m; void add_edge(int u,int v,int w) { edge[top].v=v,edge[top].w=w; edge[top].next=head[u]; head[u]=top++; } void solve() { memset(visited,false,sizeof(visited)); memset(sum,0,sizeof(sum)); for(int i=1;i<=n;i++) { dist[i][0]=inf; dist[i][1]=inf; } dist[s][0]=0; sum[s][0]=1; while(true) { int _min=inf,flag=-1,pos=-1; for(int i=1;i<=n;i++) { if(!visited[i][0]&&_min>dist[i][0]) _min=dist[i][0],pos=i,flag=0; else if(!visited[i][1]&&_min>dist[i][1]) _min=dist[i][1],pos=i,flag=1; } if(pos==-1) break; visited[pos][flag]=true; for(int i=head[pos];i!=-1;i=edge[i].next) { int v=edge[i].v,w=edge[i].w; int temp=dist[pos][flag]+w; if(temp