P1744 采購特價商品 題解(講解圖論)
阿新 • • 發佈:2019-04-18
最短 inf info target ping 分享 組成 printf 。。
圖論的超級初級題目(模板題)
最短路徑的模板題
圖是啥?(白紙上的符號?)
對於一個擁有n個頂點的無向連通圖,它的邊數一定多於n-1條。若從中選擇n-1條邊,使得無向圖仍然連通,則由n個頂點及這 n-1條邊(弧)組成的圖被稱為原無向圖的生成樹。
換句話說,有邊有點就是圖。(本蒟蒻的理解是這樣。。QWQ)
另外,還有一些與圖有關的定義(很好理解,通俗一點):
階:圖中點的個數。
邊:兩個點間的連接
權值:邊的長度
。。。想了解更多找度娘,她可能講的比我通俗QWQ。
鄰接矩陣:
進入正題:
題目背景
《愛與愁的故事第三彈·shopping》第一章。
題目描述
中山路店山店海,成了購物狂愛與愁大神的“不歸之路”。中山路上有n(n<=100)家店,每家店的坐標均在-10000~10000之間。其中的m家店之間有通路。若有通路,則表示可以從一家店走到另一家店,通路的距離為兩點間的直線距離。現在愛與愁大神要找出從一家店到另一家店之間的最短距離。你能幫愛與愁大神算出嗎?
輸入輸出格式
輸入格式:
共n+m+3行:
第1行:整數n
第2行~第n+1行:每行兩個整數x和y,描述了一家店的坐標
第n+2行:整數m
第n+3行~第n+m+2行:每行描述一條通路,由兩個整數i和j組成,表示第i家店和第j家店之間有通路。
第n+m+3行:兩個整數s和t,分別表示原點和目標店
輸出格式:
僅一行:一個實數(保留兩位小數),表示從s到t的最短路徑長度。
輸入輸出樣例
輸入樣例#1: 復制5 0 0 2 0 2 2 0 2 3 1 5 1 2 1 3 1 4 2 5 3 5 1 5輸出樣例#1: 復制
3.41
說明
100%數據:n<=100,m<=1000
先預處理轉化為鄰接矩陣後再直接輸出就可以了
具體算法為Floyd算法
上AC代碼:
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> using namespace std; int n,m,a[101][2],e,g,aa,bb;//a用來存x,y坐標 double f[101][101];//f用來存路徑的 int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) cin>>a[i][0]>>a[i][1]; //scanf("%d%d",&a[i][0],&a[i][1]); scanf("%d",&m); memset(f,0x7f,sizeof(f)); for(int i=1;i<=m;i++) { scanf("%d%d",&e,&g);//代替x,y ,因為cmath中有x,y了(真的很無語啊) f[g][e]=sqrt(pow(double(a[e][0]-a[g][0]),2)+pow(double(a[e][1]-a[g][1]),2)); f[e][g]=sqrt(pow(double(a[e][0]-a[g][0]),2)+pow(double(a[e][1]-a[g][1]),2)); } scanf("%d%d",&aa,&bb); for(int k=1;k<=n;k++)//開啟O(n^3)暴力模式—— for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if((i!=j)&&(i!=k)&&(j!=k)&&(f[i][j]>(f[i][k]+f[k][j]))) f[i][j]=f[i][k]+f[k][j]; } printf("%0.2lf",f[aa][bb]);//暴力過後松一口氣,直接輸出您想要的點就行了 return 0; }
完結?ヽ(°▽°)ノ?
希望對大家有所幫助
P1744 采購特價商品 題解(講解圖論)