题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2923
Einbahnstrasse
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3780 Accepted Submission(s): 1209
Problem Description
Einbahnstra e (German for a one-way street) is a street on which vehicles should only move in one direction. One reason for having one-way streets is to facilitate a smoother flow of traffic through crowded areas. This is useful in city centers, especially old cities like Cairo and Damascus. Careful planning guarantees that you can get to any location starting from any point. Nevertheless, drivers must carefully plan their route in order to avoid prolonging their trip due to one-way streets. Experienced drivers know that there are multiple paths to travel between any two locations. Not only that, there might be multiple roads between the same two locations. Knowing the shortest way between any two locations is a must! This is even more important when driving vehicles that are hard to maneuver (garbage trucks, towing trucks, etc.)
You just started a new job at a car-towing company. The company has a number of towing trucks parked at the company’s garage. A tow-truck lifts the front or back wheels of a broken car in order to pull it straight back to the company’s garage. You receive calls from various parts of the city about broken cars that need to be towed. The cars have to be towed in the same order as you receive the calls. Your job is to advise the tow-truck drivers regarding the shortest way in order to collect all broken cars back in to the company’s garage. At the end of the day, you have to report to the management the total distance traveled by the trucks.
Input
Your program will be tested on one or more test cases. The first line of each test case specifies three numbers (N , C , and R ) separated by one or more spaces. The city has N locations with distinct names, including the company’s garage. C is the number of broken cars. R is the number of roads in the city. Note that 0 < N < 100 , 0<=C < 1000 , and R < 10000 . The second line is made of C + 1 words, the first being the location of the company’s garage, and the rest being the locations of the broken cars. A location is a word made of 10 letters or less. Letter case is significant. After the second line, there will be exactly R lines, each describing a road. A road is described using one of these three formats:
A -v -> B
A <-v - B
A <-v -> B
A and B are names of two different locations, while v is a positive integer (not exceeding 1000) denoting the length of the road. The first format specifies a one-way street from location A to B , the second specifies a one-way street from B to A , while the last specifies a two-way street between them. A , “the arrow”, and B are separated by one or more spaces. The end of the test cases is specified with a line having three zeros (for N , C , and R .)
The test case in the example below is the same as the one in the figure.
Output
For each test case, print the total distance traveled using the following format:
k . V
Where k is test case number (starting at 1,) is a space, and V is the result.
Sample Input
4 2 5
NewTroy Midvale Metrodale
NewTroy <-20-> Midvale
Midvale –50-> Bakerline
NewTroy <-5– Bakerline
Metrodale <-30-> NewTroy
Metrodale –5-> Bakerline
0 0 0
Sample Output
1. 80
Source
2008 ANARC
题意:
每组测试数据首先给出三个数:n , c , r ;n代表出现地点的个数,c车库和需要去清理车辆碎片的地点数,r代表给出的道路数目,这个所给的道路数目有三种类型,单向从u到v,单向从v到u,双向道路。最后让你求出将所有需要清理的车辆带回车库所行驶的最小距离。
最后的输出格式k . V,k表示是第几组数据,V表示所行驶的最小距离。
因为图中给的道路是单向的,又需要求几个来回过程。所以用Floy算法求出任意两点的最短距离更适合本题。
开始的时候因为对道路类型判断有点问题,所以总是wrong answer
下面是那段判断有误的代码(以此为戒):
if(s5[0]=='-')
{
for(int j=2;j<len3;j++)
if(s5[j]>='0'&&s5[j]<='9')
w=w*10+s5[j]-'0';
if(map[t1][t2]>w)
map[t1][t2]=w;
}
else if(s5[len3-1]=='>')
{
for(int j=2;j<len3;j++)
if(s5[j]>='0'&&s5[j]<='9')
w=w*10+s5[j]-'0';
if(map[t1][t2]>w)
{
map[t1][t2]=w;
map[t2][t1]=w;
}
}
else
{
for(int j=2;j<len3;j++)
if(s5[j]>='0'&&s5[j]<='9')
w=w*10+s5[j]-'0';
if(map[t2][t1]>w)
map[t2][t1]=w;
}
AC代码:
#include<stdio.h>
#include<string.h>
#include<string>
#include<iostream>
using namespace std;
#define INF 0x3f3f3f3f
int map[1025][1025];
string s[1025];
int len,x[1005];
int check(string ss)
{//映射,将字符串放在一个字符数组中并可查到每个字符串的下标
for(int i=0;i<=len;i++)
if(s[i]==ss)
return i;
s[++len]=ss;
return len;
}
int main()
{
int n,c,r,k=0;
while(~scanf("%d %d %d",&n,&c,&r))
{
if(n==0&&c==0&&r==0)
break;
for(int i=0;i<=1005;i++)
for(int j=0;j<=1005;j++)
{
if(i!=j)
map[i][j]=INF;
else
map[i][j]=0;
}
string ss;
cin>>ss;
s[0]=ss;
len=0;
for(int i=1;i<=c;i++)
{//有破碎汽车的地点
cin>>ss;
int tt=check(ss);
x[i]=tt;//记录有破碎汽车的地点
}
for(int i=0;i<r;i++)
{
string s1,s3;
char s4[105],s5[105],s6[105];
int w=0,len1,len2,len3;
scanf("%s",s4);
scanf("%s",s5);
scanf("%s",s6);
len1=strlen(s4);
len2=strlen(s6);
len3=strlen(s5);
for(int j=0;j<len1;j++)
s1+=s4[j];
for(int j=0;j<len2;j++)
s3+=s6[j];
int t1=check(s1);//映射字符串下标
int t2=check(s3);//映射字符串下标
for(int j=2;j<len3;j++)
if(s5[j]>='0'&&s5[j]<='9')
w=w*10+s5[j]-'0';//两点之间距离用变量w记录
if(s5[len3-1]=='>'&&map[t1][t2]>w)
map[t1][t2]=w;
if(s5[0]=='<'&&map[t2][t1]>w)
map[t2][t1]=w;
}
for(int k=0; k<n; k++)
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
{//弗洛伊德函数求得图中每两点之间的最短距离
if(map[i][k]+map[k][j]<map[i][j])
map[i][j]=map[i][k]+map[k][j];
}
int dis=0;
for(int i=1;i<=c;i++)
dis+=map[0][x[i]]+map[x[i]][0];
printf("%d. %d\n",++k,dis);
}
return 0;
}