题意:
n个城市,c辆破车,r条路,求从公司出发把所有破车拖回(一次拖一个)的最少路程
思路:floyd算法或dijkstra算法;
WA了10次=_=(崩溃。。)用dijkstra的时候没用position存位置WA了2次,用floyd的时候没初始化cas,真想一头撞死在豆腐上。
注意:每座城市可能有好几辆破车,不仅要开过去还要拉回来
附上代码。。
floyd版
#include<cstdio>
#include<cstring>
#define INF 0x3f3f3f3f
#define N 100
int road[N+10][N+10];
char name[N+10][15];
int number;
int position[N*10+10];
void floyd(int n)
{
for(int k=1; k<=n; k++)
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
{
//printf("%d->%d:%d %d>%d:%d %d->%d:%d\n",i,j,road[i][j],i,k,road[i][k],k,j,road[k][j]);
if((road[i][k]!=INF)&&(road[k][j]!=INF)&&(road[i][j]>road[i][k]+road[k][j]))
{
road[i][j]=road[i][k]+road[k][j];
//printf("i=%d j=%d dis=%d\n",i,j,road[i][j]);
}
}
}
int findname(char *s)//找城市名字所对应的城市编号
{
int i;
for(i=1;i<=number;i++)
if(strcmp(s,name[i])==0)
return i;
strcpy(name[number+1],s);
number+=1;
return number;
}
int main()
{
int n,c,r,i,cas=0;
while(scanf("%d%d%d",&n,&c,&r)!=EOF)
{
if(!n&&!c&&!r)break;
memset(road,0x3f,sizeof(road));//初始化
for(i=1;i<=n;i++)
road[i][i]=0;
number=0;//当前已有城市编号
for(i=1;i<=c+1;i++)
{
char s[15];
scanf("%s",s);
int t=findname(s);
position[i]=t;
}
for(i=1;i<=r;i++)
{
char s1[25],s2[25],s3[25];
scanf("%s%s%s",s1,s2,s3);
int t1=findname(s1);
int t3=findname(s3);
int t2=0;
for(int j=0;s2[j]!='\0';j++)//算值
if(s2[j]>='0'&&s2[j]<='9')
t2=t2*10+s2[j]-'0';
// printf("%d\n",t2);
if(s2[0]=='<')
{
if(road[t3][t1]>t2)
road[t3][t1]=t2;
}
if(s2[strlen(s2)-1]=='>')
{
if(road[t1][t3]>t2)
road[t1][t3]=t2;
}
}
floyd(n);
int ans=0;
for(i=2;i<=c+1;i++)
{
ans=ans+road[1][position[i]]+road[position[i]][1];
}
cas++;
printf("%d. %d\n",cas,ans);
}
return 0;
}
dijkstra版
#include<cstdio>
#include<cstring>
#define INF 0x3f3f3f3f
#define N 100
int dist[N+10],vis[N+10],road[N+10][N+10];
char name[N+10][15];
int number;
int position[N*10+10];
void dijkstra(int from,int n)
{
memset(vis,0,sizeof(vis));
memset(dist,0x3f,sizeof(dist));
dist[from]=0;
int i,j,now=-1,last=-1;
for(i=1;i<=n;i++)
{
int mi=INF;
for(j=1;j<=n;j++)
if(!vis[j]&&dist[j]<mi)
{
now=j;
mi=dist[j];
}
if(last==now)break;
last=now;
vis[now]=1;
for(j=1;j<=n;j++)
if(dist[j]>dist[now]+road[now][j])
dist[j]=dist[now]+road[now][j];
}
}
int findname(char *s)
{
int i;
for(i=1;i<=number;i++)
if(strcmp(s,name[i])==0)
return i;
strcpy(name[number+1],s);
number+=1;
return number;
}
int main()
{
int n,c,r,i,cas=0;
while(scanf("%d%d%d",&n,&c,&r)!=EOF)
{
if(!n&&!c&&!r)break;
memset(road,0x3f,sizeof(road));
for(i=1;i<=n;i++)
road[i][i]=0;
number=0;
for(i=1;i<=c+1;i++)
{
char s[15];
scanf("%s",s);
int t=findname(s);
position[i]=t;
}
for(i=1;i<=r;i++)
{
char s1[25],s2[25],s3[25];
scanf("%s%s%s",s1,s2,s3);
int t1=findname(s1);
int t3=findname(s3);
int t2=0;
for(int j=0;s2[j]!='\0';j++)
if(s2[j]>='0'&&s2[j]<='9')
t2=t2*10+s2[j]-'0';
// printf("%d\n",t2);
if(s2[0]=='<')
{
if(road[t3][t1]>t2)
road[t3][t1]=t2;
}
if(s2[strlen(s2)-1]=='>')
{
if(road[t1][t3]>t2)
road[t1][t3]=t2;
}
}
dijkstra(1,n);
int ans=0;
for(i=2;i<=c+1;i++)
ans+=dist[position[i]];//去
for(i=2;i<=c+1;i++)//回
{
dijkstra(position[i],n);
ans+=dist[1];
}
cas++;
printf("%d. %d\n",cas,ans);
}
return 0;
}