/*
标题:zju 3396 Conference Call
整理:赖敬峰
时间:2013-04-29 03:22:35
更新:2013-04-29 03:22:38
算法:最短路
说明:
求连接三个点的最小代价(重复的算一次)
------
思路是在图中找一个点,到三点的距离和最小
当然不能枚举每个点贪心尝试...做题时陷进这里卡住了...
最短距离是相对的,所以只要求三点到其他点的最短距离就好了
*/
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define INF 0x2f2f2f2f
int arr[10002];
struct NN{int t,next,c;};
NN nn[20005];
int dis[3][505];
bool vi[505];
int head[505],en;
int mymin(int a,int b){return a<b?a:b;}
void init()
{
memset(head,-1,sizeof(head));
en=0;
}
void add(int f,int t,int c)
{
nn[en].t=t;
nn[en].c=c;
nn[en].next=head[f];
head[f]=en++;
nn[en].t=f;
nn[en].c=c;
nn[en].next=head[t];
head[t]=en++;
}
void spfa(int s,int m,int mod)
{
queue<int> qq;
while(!qq.empty()) qq.pop();
qq.push(s);
memset(vi,0,sizeof(vi));
vi[s]=1;
dis[mod][s]=0;
int i,j,k;
while(!qq.empty())
{
i=qq.front();qq.pop();vi[i]=0;
for(j=head[i];j!=-1;j=nn[j].next)
{
k=nn[j].t;
if(dis[mod][i]+nn[j].c<dis[mod][k])
{
dis[mod][k]=dis[mod][i]+nn[j].c;
if(!vi[k])
{
vi[k]=1;
qq.push(k);
}
}
}
}
}
int main()
{
int n,m,k;
int i,j;
int f,t,c,q,x,y,z;
int ans;
int cas=1;
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
init();
for(i=1;i<=n;i++) scanf("%d",&arr[i]);
for(i=0;i<k;i++)
{
scanf("%d%d%d",&f,&t,&c);
add(f,t,c);
}
scanf("%d",&q);
printf("Case #%d\n",cas++);
for(i=1;i<=q;i++)
{
scanf("%d%d%d",&x,&y,&z);
x=arr[x];y=arr[y];z=arr[z];
memset(dis,0x2f,sizeof(dis));
spfa(x,m,0);spfa(y,m,1);spfa(z,m,2);
for(ans=INF,j=1;j<=m;j++) ans=mymin(ans,dis[0][j]+dis[1][j]+dis[2][j]);
printf("Line %d: ",i);
if(ans>=INF) printf("Impossible to connect!\n");
else printf("The minimum cost for this line is %d.\n",ans);
}
}
return 0;
}
zju 3396 Conference Call
最新推荐文章于 2023-05-26 20:47:27 发布