1. 程式人生 > >SDUT 2622 最短路徑(Dijkstra)

SDUT 2622 最短路徑(Dijkstra)

點我看題目

題意 :中文不詳述。

思路 :因為這個題加了一個要求就是路徑數目得是x的倍數。所以在原來演算法的一維dis陣列增加到二維,用來存走的路徑數%x。也可以用spfa做。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>

using namespace std ;

#define LL long long
const int maxn = 110 ;
const int maxm = 10010 ;
bool
vis[maxn][maxn] ; const LL INF = 1LL<<60 ; int cnt = 0 ; int head[maxn] ; LL dist[maxn][maxn] ; int n , m ; struct node { int u,v,w ; int next ; }Edge[maxm] ; void addedge(int u,int v,int w) { Edge[cnt].u = u ; Edge[cnt].v = v ; Edge[cnt].w = w ; Edge[cnt].next
= head[u] ; head[u] = cnt++ ; } LL dijkstra(int s,int t,int x) { for(int i = 0 ; i < n ; i++) for(int j = 0 ; j < x ; j++) { dist[i][j] = INF ; vis[i][j] = false ; } dist[s][0] = 0 ; while(true) { LL minn = INF ; int
u = -1 ; int flag , xx ; for(int i = 0 ; i < n ; i++) { for(int j = 0 ; j < x ; j++) { if(!vis[i][j] && minn > dist[i][j]) { minn = dist[i][j] ; u = i ; flag = j ; xx = (flag+1)%x ; } } } if(u == -1) return -1 ; vis[u][flag] = true ; if(vis[t][0]) return dist[t][0] ; for(int j = head[u] ; j != -1 ; j = Edge[j].next) { int v = Edge[j].v ; if(!vis[v][xx] && minn + Edge[j].w < dist[v][xx]) dist[v][xx] = minn + Edge[j].w ; } } } int main() { int T,s,t,x ; scanf("%d",&T) ; while(T--) { cnt = 0 ; memset(head,-1,sizeof(head)) ; // memset(vis,false,sizeof(vis) ) ; scanf("%d %d",&n,&m) ; int u,v, w ; for(int i = 0 ; i < m ; i++) { scanf("%d %d %d",&u,&v,&w) ; addedge(u,v,w) ; } scanf("%d %d %d",&s,&t,&x) ; LL ans = dijkstra(s,t,x) ; if(ans != -1) printf("%lld\n",dist[t][0]) ; else printf("No Answer!\n") ; } return 0 ; }
View Code