標籤:
Description2008年將到,王飛同學化了九牛二虎之力搞到了2張2008年奧運會足球賽決賽的門票。真是開心啊!他爸爸準備開車跟他一起去北京看球賽。不過門票費好貴啊,所以他爸爸說了,這個錢要在下學期的生活費裡扣(好摳門),不過如果他能讓從杭州去北京的油費最省(油價最近漲的好厲害啊),那麼就不扣生活費了。哈哈,這個就難不倒他了。在ACM裡可不是白混的。很快他算出了汽車從杭州到北京必須要加幾次油,並查出了到北京要經過哪幾個城市,每個城市有哪些加油站以及從某城市各加油站到另一城市各加油站的距離和路況算出了各加油站之間的耗油量。下面是不是很easy?Input有多個測試案例。第一行先輸入測試案例的數目T。對於每個測試案例,第一行輸入一個整數n表示將在中途n(0 < n < 40)個城市中加油,後面緊跟著是n個整數代表每個城市有幾個加油站(每個城市加油站不超過10個)。以下n+1行,每行由3個Si,Ej,L一組組成的好幾對整數,該行以0結束。表示從前一城市Si第i個加油站(杭州的話就是家拉)出發到該城市第j個加油站消耗的油量為L升。Output對於每個測試,輸出一行,內容為最小總耗油量。Sample Input
12 2 31 1 3 1 2 1 01 1 2 1 2 7 2 1 8 2 2 9 2 3 4 01 1 5 2 1 6 3 1 6 0
Sample Output
10
看該題之前先弄清楚dijkstra演算法,先看道簡單的題
一共有n個頂點,共m條邊,每條邊由三個資料群組成x,y,z,分別表示開始,結束,和需要走的路程,要求輸出最短路程走到最終n
7 10
1 2 3
1 3 1
2 4 2
2 5 7
3 4 8
3 5 9
3 6 4
4 7 5
5 7 6
6 7 6
#include<cstdio>#include<cstring>using namespace std;const int inf = 0x3f3f3f3f, MAX = 300;int min1,x,y,z,k,n,m;int map[MAX][MAX],p[MAX],d[MAX];void dijkstra(int map[][MAX],int n){ for(int i = 1; i <= n ; i++) d[i] = inf; d[1] = 0; for(int i = 1; i <= n ; i++){ min1 = inf; for(int j = 1; j <= n ; j++){ if(!p[j] && d[j] < min1){ min1 = d[j]; k = j; } } p[k] = 1; for(int j = 1; j <= n ; j++){ if(!p[j] && d[j] > d[k] + map[k][j]) d[j] = d[k] + map[k][j]; } } printf("%d",d[n]);}int main(){ memset(p,0,sizeof(p)); scanf("%d%d",&n,&m); for(int i = 1; i <= n; i++) for(int j = 1; j <= n ; j++) map[i][j] = inf; for(int i = 1; i <= m ; i++){ scanf("%d%d%d",&x,&y,&z); map[x][y] =z; } dijkstra(map,n); return 0;}
View Code
dijkstra演算法是用來算從一個頂點到另一個頂點最短路徑的演算法,用p來記憶是否走過這條路,用d來記憶最短路徑,map用來記憶從x到y需要走的路程。
p先清零,然後在第一個小for迴圈中得到最小的路徑的下標,將這個點記錄下來已經走過了,第二個for用來更新從起點開始的最短路,的d[1] = 0,即從1點開始走,將map全都初始化為無窮大,那麼在記錄資料的時候真正記錄的就有了長度,而無窮大就看做是不能走。
現在看原題。
題意:從一個起始點開始走,中間有好多點,要求最後走到終點。
難在輸入。開始輸入測試組,再輸入有幾個城市,每個城市分別得加油站的個數。在下一行輸入每個加油站的起點和終點以及距離,最後輸出。
#include<cstdio>#include<cstring>using namespace std;const int inf = 0x3f3f3f3f,MAX = 300;int min1, n, m,i, j, k, x, y, z;int map[MAX][MAX],p[MAX],d[MAX];void dijkstra(int map[MAX][MAX],int n){ d[1] = 0; for(int i = 1; i <= n; i++){ min1 = inf; for(int j = 1; j <= n ;j++){ if(!p[j] && d[j] > min1){ d[j] = min1; k = j; } } p[k] = 1; for(int j = 1; j <= n; j++) if(!p[j] && d[j] > d[k] + map[k][j]); d[j] = d[k] + map[k][j]; } printf("%d\n",d[n]);}int main(){ int T,m,t[MAX],t1[MAX],temp; scanf("%d",&T); while(T--){ n = 0; t[1] = 1; t1[1] = 0; t1[0] =0; scanf("%d",&m); for(int i = 2; i <= m+1 ; i++){ scanf("%d",&t[i]); n+=t[i];//n用來儲存所有的個數 } n+=2; for(int i = 0; i <= n ; i++) for(int j = 0; j <= n; j++) map[i][j] = inf; for(int i = 2; i <= m+1; i++) for(int j = 1; j < i ;j++) t1[i] += t[j];//t1用來出儲存前面的個數,t用來儲存當前的個數 for(int i = 2; i <= m+2; i++){ for(int k = 1; k <= t[i]; k++){ scanf("%d%d%d",&x,&y,&z); map[t1[i-2]+x][t1[i-1]+y] = z; } scanf("%d",temp); } memset(p,0,sizeof(p)); dijkstra(map,n); } return 0;}
View Code
沒有過的碼-0-心煩晚點再改,輸入一直錯誤。
去北京看奧運