杭电2923————Folyd
题目链接:点击打开链接
这个题目其实很简单,就是各种坑。
1.同一个地方破车可能有多辆。
2.每次拖完一辆破车必须回来,不能全部一次性拖完所有的....//一开始题意弄错了在这个地方纠结了很久
3.因为城市是用字符串的形式存储的,所以需要自己定义一个映射,当然c++用map也可以。
以上这些处理完之后,跑一边Floyd就可以了。网上看题解有跑两边Dijkstra的,这样会快很多。
没有用map,62ms
#include <cstdio> #include <cstring> #include <iostream> #include <queue> #define maxn 105 #define INF 0x7ffffff using namespace std; int cases = 0; int cnt = 0; int N,C,R; int G[maxn][maxn]; char city[maxn][20]; char car[1005][20]; int Min(int x,int y) { return (x < y) ? x : y; } void init() { cnt = 0 ; for(int i = 0 ; i < maxn ; ++i) for(int j = 0 ; j < maxn ; ++j) G[i][j] = INF; memset(city,0,sizeof(city)); memset(car,0,sizeof(car)); } int FindCity(char *s) { for(int i = 0 ; i < cnt ; ++i) if(strcmp(city[i],s) == 0) return i; //如果没有找到的话 return -1; } int main() { char temp[maxn] = {0},temp1[maxn] = {0},temp2[maxn] = {0}; char from,to; int value; while(cin >> N >> C >> R){ if(N == 0 && C == 0 && R == 0) break; init(); for(int i = 0 ; i <= C ; ++i){//C+1 cin >> temp; strcpy(car[i],temp);//破车 if(FindCity(temp) == -1) strcpy(city[cnt++],temp); } while(R--){ scanf("%s %c-%d-%c %s",temp1,&from,&value,&to,temp2); int v1 = FindCity(temp1); int v2 = FindCity(temp2); if(v1 == -1){ strcpy(city[cnt++],temp1); v1 = cnt-1; } if(v2 == -1){ strcpy(city[cnt++],temp2); v2 = cnt -1; } if(from == '<') G[v2][v1] = Min(G[v2][v1],value); if(to == '>') G[v1][v2] = Min(G[v1][v2],value); } //Floyd for(int k = 0 ; k < N ; ++k) for(int i = 0 ; i < N ; ++i) for(int j = 0 ; j < N ; ++j) G[i][j] = Min(G[i][j],G[i][k]+G[k][j]); //可能有多辆破车 int sum = 0; for(int i = 1 ; i <= C ; ++i){ int v = FindCity(car[i]); sum += G[0][v] + G[v][0]; } printf("%d. %d\n",++cases,sum); } return 0; }
用了map,156ms,转自:点击打开链接
#include <iostream> #include <stdio.h> #include <cstring> #include <map> #include <algorithm> using namespace std; #define inf 999999999 const int L = 1005; int n,c,m; int a[105][105]; char str[1005][100]; int cnt; map<string,int> mat; void Floyd() { int i,j,k; for(i = 1; i<=n; i++) for(j = 1; j<=n; j++) for(k = 1; k<=n; k++) if(a[j][i]+a[i][k]<a[j][k]) a[j][k] = a[j][i]+a[i][k]; } int main() { int i,j,val,x,y,len,cas = 1,sum,start; char s1[100],s2[100],s3[100]; char from,to; while(~scanf("%d%d%d",&n,&c,&m)&&(n+c+m)) { sum = 0; mat.clear(); for(i = 0; i<=n; i++) for(j = 0; j<=n; j++) a[i][j] = inf; for(i = 0; i<=c; i++) scanf("%s",str[i]); cnt = 1; for(i = 0; i<m; i++) { scanf("%s %c-%d-%c %s",s1,&from,&val,&to,s3); if(!mat[s1]) mat[s1] = cnt++; if(!mat[s3]) mat[s3] = cnt++; x = mat[s1],y = mat[s3]; if(from == '<' && val<a[y][x]) a[y][x] = val; if(to == '>' && val<a[x][y]) a[x][y] = val; } Floyd(); start = mat[str[0]]; for(i = 1; i<=c; i++) sum+=a[start][mat[str[i]]]+a[mat[str[i]]][start]; printf("%d. %d\n",cas++,sum); } return 0; }