Cab

题目描述

HJ,LWC,HRQ三个人在外面比赛,比赛前他们想去外面玩,但是三个人相去的地方不一样。他们坐一辆出租车,请问怎么走,把他们三个都送到目的地的路程最短?

输入

第一行是一个整数K(K<=100),表示样例的个数。每个样例的第一行是两个整数V(3≤V≤1,000),E(E≤40,000),分别表示地点数和街道的数目。地点的编号从1到V,他们的起点编号为0。第二行是三个整数,依次表示三个人想去的地点的编号。以后的E行,每行是一条街道的信息,包含三个整数D,S(0≤D,S≤V),C(1≤C≤100),表示地点D和地点S之间里程为C。输入保证所有地点是可达的,所有的路都是唯一,双向的。

输出

每行输出一个样例的结果,为一个整数,即最短路程的里程数。

样例输入

1
4 7
1 2 3
0 1 4
0 2 5
0 3 6
0 4 1
1 4 2
2 4 3
3 4 2

样例输出

12

题意:三个人去不同的地方,求将他们都送到目的地的最短距离
题解:spfa+排列,求出起点与三个点之间的最短路,然后全排列即可
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<string.h>
#include<set>
#define inf 100000000
using namespace std;
int visit[1005];
int pre[1005];
int des[1005];
int save[4];
int sg[4][4];
int n,m;
struct lmx{
 int to;
 int next;
 int w;
};
lmx lm[80004];
int spfa(int ii,int jj)
{
 int i;
 int sr=save[ii];
 int de=save[jj];
 queue<int> q;
 memset(visit,0,sizeof(visit));
 for(i=0;i<=n;i++) des[i]=inf;
 visit[sr]=1;
 des[sr]=0;
    q.push(sr);
 while(!q.empty())
 {
  int b=q.front();
  q.pop();
  visit[b]=0;
  for(i=pre[b];i!=-1;i=lm[i].next)
  {
            if(des[lm[i].to]>des[b]+lm[i].w)
   {
    des[lm[i].to]=des[b]+lm[i].w;
    if(visit[lm[i].to]==0)
    {
     visit[lm[i].to]=1;
     q.push(lm[i].to);
    }
   }
  }
 }
 return des[de];
}
int main()
{
    int test,a,b,c,i,x,cnt,sum,ce,j;
 char ss[5]="0123";
 set<int> s;
 scanf("%d",&test);
 while(test--)
 {
  s.clear();
  ce=inf;
  cnt=0;
  scanf("%d %d",&n,&m);
  save[0]=0;
        for(i=0;i<3;i++)
  {
   scanf("%d",&x);
   s.insert(x);
  }
  set<int>::iterator it;
  for(it=s.begin();it!=s.end();it++)
  {
            save[++cnt]=*it;
  }
  memset(pre,-1,sizeof(pre));
  int pp=0;
  for(i=0;i<m;i++)
  {
   scanf("%d %d %d",&a,&b,&c);
      lm[pp].to=b;
   lm[pp].next=pre[a];
   lm[pp].w=c;
   pre[a]=pp++;
   swap(a,b);
            lm[pp].to=b;
   lm[pp].next=pre[a];
   lm[pp].w=c;
   pre[a]=pp++;
  }
  memset(sg,0,sizeof(sg));
        for(i=0;i<=cnt;i++)
  {
   for(j=0;j<=cnt;j++)
   {
    if(i!=j)
    {
     sg[i][j]=spfa(i,j);
    }
   }
  }
  do{
              sum=0;
     for(i=0;i<cnt;i++) sum+=sg[ss[i]-'0'][ss[i+1]-'0'];
     if(sum<ce) ce=sum;
  }while(next_permutation(ss+1,ss+cnt+1));
  printf("%d\n",ce);
 }
 return 0;
}

posted @ 2013-09-30 14:32  forevermemory  阅读(341)  评论(0编辑  收藏  举报