洛谷 P1744 采購特價商品
阿新 • • 發佈:2018-04-05
gpo 鏈表 情況 分享 AD clas radi namespace 題目
洛谷 P1744 采購特價商品
題目背景
《愛與愁的故事第三彈·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
4.4 晚上,學妹問我這道題,其實是很久之前做的了,剛開始一看題目還以為是DP(背包) hua ji
思路:根據每個點的 x,y 坐標 求出每兩點間的直線距離(兩點間距離公式:sqrt( ( x1-x2 ) * ( x1-x2 ) + ( y1-y2 ) * ( y1-y2 ) ) )
然後跑一遍SPFA,完事兒
/*有些地方稍微給學妹改了一下,但大體是沒動的,希望學妹不要介意啊 2333*/ #include<algorithm> #include<iostream> #include<cstdio> #include<cmath> #define MAXN 100000000 using namespace std; double a[101][3], d[1010], b[1010]; int n, m, x, y, c[1010][3], Q, W; int main() { cin >> n; for(int學妹的代碼i = 1; i <= n; i++) cin >> a[i][1] >> a[i][2]; cin >> m; for(int i = 1; i <= m; i++) d[i] = MAXN, c[i][1] = MAXN, c[i][2] = MAXN; for(int i = 1; i <= m; i++) { cin >> x >> y, c[i][1] = x, c[i][2] = y; b[i] = sqrt(pow(a[x][1]-a[y][1], 2) + pow(a[x][2]-a[y][2], 2)); } cin >> Q >> W; d[Q] = 0; for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { if(d[c[j][1]]+b[j] < d[c[j][2]]) d[c[j][2]] = d[c[j][1]]+b[j]; if(d[c[j][2]]+b[j] < d[c[j][1]]) d[c[j][1]] = d[c[j][2]]+b[j]; } } printf("%.2f", d[W]); return 0; }
突然發現有些看不懂學妹的代碼 2333 (放假回來讓學妹講講)
#include<algorithm> #include<cstring> #include<utility> #include<cstdio> #include<cmath> #include<queue> #define M 10005 #define MAXN 0x7fffffff using namespace std; queue<int> q; pair<int, int> pa[105]; //存邊的橫(first)縱(second)坐標 int n, m; int tot; double dis[M], cap[M]; //開double 確保精度 int to[M], net[M], head[M], vis[M]; void add(int u, int v, double w) { //鄰接鏈表存邊,這樣比用結構體存快一些,因為結構體還需要從裏邊調出來 to[++tot] = v; net[tot] = head[u]; head[u] = tot; cap[tot] = w; to[++tot] = u; net[tot] = head[v]; head[v] = tot; cap[tot] = w; } void spfa(int x) { //樸素的spfa for(int i = 1; i <= n; i++) dis[i] = 1.0 * MAXN, vis[i] = 0; dis[x] = 0.0; vis[x] = 1; q.push(x); while(!q.empty()) { int y = q.front(); q.pop(); vis[y] = 0; for(int i = head[y]; i; i = net[i]) { int t = to[i]; if(dis[t] > dis[y] + cap[i]) { dis[t] = dis[y] + cap[i]; if(!vis[t]) vis[t] = 1, q.push(t); } } } } int main() { scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d%d", &pa[i].first, &pa[i].second); scanf("%d", &m); for(int i = 1; i <= m; i++) { int a, b; double c; scanf("%d%d", &a, &b); c = sqrt(double((pa[a].first-pa[b].first)*(pa[a].first-pa[b].first))+double((pa[a].second-pa[b].second)*(pa[a].second-pa[b].second))); //精度很重要 add(a, b, c); //在兩點間有通路的情況下求兩點間距離、存邊 } int s, tmp; scanf("%d%d", &s, &tmp); spfa(s); printf("%.2lf",dis[tmp]); return 0; }既然看不懂學妹的,那就好好寫題解吧
洛谷 P1744 采購特價商品