zoj 3396 Conference Call



Good News! Utopia Polycom begins to offer a whole new service, Conference Call. This new service enables three users to make phone calls at the same time and talk to each other. It‘s very useful when several people are discussing about one shared topic. For
example, Tom, Rosemary and you plan to go picnic tomorrow. You just need to make one conference call, so that you can discuss with Tom and Rosemary simultaneously. It‘s extremely convenient, yes?

However, it has a lot of technological problems to start this service. It took engineers of Utopia Polycom five years to conquer all these problems. One of the biggest problem is how to make the communication line connected. To solve this problem, they have
constructed a powerful net of transfer stations. Every single phone is connected to its nearest transfer station, some transfer stations are connected to each other by wires. When to make a conference call, signal will start from the dialling telphone. The
signal will be transferred through transfer stations and finally reach the other two phones.

Since the distances between each two transfer stations are various, the cost for the signal to go through the wires is different as well. Assume there are
n telphones(numbered from 1 to n) and m(numbered from
1 to m) transfer stations in this communication net. The total cost for a line is the sum of the costs of the wires in the line. Our problems remains, what is the minimal total cost to make a conference call among three telphone
a, b and c. As showing below, the minimal total cost to make a conference call among telphone
1, 2, 3 is 12.

Input

There are multiple cases. For each test case, the first line contain three positive integers,
n (n ≤ 10000), m (m ≤ 500), l (l ≤ 10000).
l means the number of wires. Then follows n lines. Each line contains one integer
ti (1 ≤ ti
m), which means the number of transfer station No.i telphone is connected to. Then follows
l lines, each line contains three integers a, b, C (1 ≤
C ≤ 500), which means a and b transfer stations are connected to each other by a wire with the amount of cost
C. If a pair (a, b) doesn‘t appear in these l lines, that means tranfer stations
a, b are not connected.

The next line is a single integer q (q ≤ 50). Then follow
q
lines. Each line contains three integers x, y, z. You are supposed to calculate the minimal total cost to make a conference call among telphone
x, y, z. Each test case is seperated by a blank line. Proceed to the end of the file.

Output

For each test case i, print case number in the form "Case #i" in one single line. Then for each inquiry
j, print one line in the form "Line j: " and if the conference call can be made and the minimal total cost is
Min, print the sentense "The minimum cost for this line is Min." else you should print "Impossible to connect!". Look at the samples for details.

Sample Input

3 5 5
2
1
5
1 2 6
2 3 1
3 4 2
4 5 3
1 5 12
1
1 2 3

3 3 1
1
2
3
2 3 4
1
1 2 3

Sample Output

Case #1
Line 1: The minimum cost for this line is 12.
Case #2
Line 1: Impossible to connect!

题意:现在某公司推出一项新项目,支持三个人之间的电话通化,每台电话连接一个最近的中转站,然而要进行通话,是需要在中转站上传输信号,传输的距离越长费用就越高,求出给定的三台电话的通话所需的最短路程。
思路:使用floyd算法就出每两个城市之间的最短路径,然后依据这些路径求出三台电话之间的最短路径。求的时候还是有一个大坑的,不能只枚举给定三个城市之间的最短路。例如:看下图,假设求A,B,C三点的最短路,如果只涉及A,B,C三点的话,求出的路径显然不是最短的,假设以D为中心,求出来的路径肯定比刚才的路径要短。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#define INF 100000000
using namespace std;
int root[10004];         //用来存储每台电话最近的中转站
int f[504][504];
int n,m,l;
void init()
{
    for(int i=0; i<=n; i++)
        for(int j=0; j<=i; j++)
        {
            if(i!=j) f[i][j]=f[j][i]=INF;
            else f[i][j]=0;
        }
}

void floyd()
{
    for(int k=1;k<=n;k++)
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    {
        if(f[i][j]>f[i][k]+f[k][j])
        {
            f[i][j]=f[i][k]+f[k][j];
        }
    }
}
int main()
{
    int ans=1;
    while(scanf("%d%d%d",&m,&n,&l)!=EOF)
    {
        init();
        for(int i=1;i<=m;i++)
        scanf("%d",&root[i]);
        int x,y,z;
        for(int i=0;i<l;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            if(f[x][y]>z) f[x][y]=f[y][x]=z;
        }
        floyd();
        scanf("%d",&l);
        printf("Case #%d\n",ans++);
        for(int i=1;i<=l;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            x=root[x];
            y=root[y];
            z=root[z];
            int sum=INF;
            for(int i=1;i<=n;i++)          //本题关键,很坑....
            {
                if(sum>f[i][x]+f[i][y]+f[i][z])
                    sum=f[i][x]+f[i][y]+f[i][z];
            }

            printf("Line %d: ",i);
            if(sum>=INF) printf("Impossible to connect!\n");
            else printf("The minimum cost for this line is %d.\n",sum);
        }
    }
    return 0;
}

zoj 3396 Conference Call

时间: 2024-08-28 18:46:51

zoj 3396 Conference Call的相关文章

ZOJ 3396 Conference Call(3点最小生成树)

题意:给出一组含m个点的无向图,再给出n个点,这n个点分别以一条边连接到这个无向图中的某个点.对于每个询问,求出3点连通的最小代价.有可能3个点是不能互通的.如图,最小代价就是红色的边的权之和. 思路:先对m个点的无向图进行求两两之间最短路径,用floyd.接下来对于每个询问,穷举m个点,求3个点分别到该点的距离之和,求最小即可. 1 //#include <bits/stdc++.h> 2 #include <iostream> 3 #include <cstdio>

概率dp ZOJ 3640

Help Me Escape Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Practice ZOJ 3640 Appoint description:  System Crawler  (2014-10-22) Description Background     If thou doest well, shalt thou not be accepted? an

zoj 2156 - Charlie&#39;s Change

题目:钱数拼凑,面值为1,5,10,25,求组成n面值的最大钱币数. 分析:dp,01背包.需要进行二进制拆分,否则TLE,利用数组记录每种硬币的个数,方便更新. 写了一个 多重背包的 O(NV)反而没有拆分快.囧,最后利用了状态压缩优化 90ms: 把 1 cents 的最后处理,其他都除以5,状态就少了5倍了. 说明:貌似我的比大黄的快.(2011-09-26 12:49). #include <stdio.h> #include <stdlib.h> #include <

ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 最小生成树 Kruskal算法

题目链接:ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 Building a Space Station Time Limit: 2 Seconds      Memory Limit: 65536 KB You are a member of the space station engineering team, and are assigned a task in the construction process of the statio

ZOJ 3607 Lazier Salesgirl (贪心)

Lazier Salesgirl Time Limit: 2 Seconds      Memory Limit: 65536 KB Kochiya Sanae is a lazy girl who makes and sells bread. She is an expert at bread making and selling. She can sell the i-th customer a piece of bread for price pi. But she is so lazy

ZOJ - 2243 - Binary Search Heap Construction

先上题目: Binary Search Heap Construction Time Limit: 5 Seconds      Memory Limit: 32768 KB Read the statement of problem G for the definitions concerning trees. In the following we define the basic terminology of heaps. A heap is a tree whose internal n

ZOJ 2859 二维线段树

思路:自己写的第二发二维线段树1A,哈哈,看来对二维的push操作比较了解了:但是还没遇到在两个线段树中同时进行push操作的,其实这题我是想在x维和y维同时进行push操作的,但是想了好久不会,然后看到这题又给出10秒,然后想想在x维线段直接单点查询肯定也过了,然后在第二维就只有pushup操作,在第一维线段树没有pushup操作.要是在第一维也有pushup操作的话,那就不用单点查询那么慢了.不过也A了,想找题即在二维同时进行pushup和pushdown操作的. #include<iost

ZOJ 2588

求一个无向图的桥(可能存在重边),输出割边的数目,并按顺序输出割边的序号(输入的顺序). 由于内存的限制 , 无法使用邻接矩阵 , 只能用邻接表了 . 第一次用了邻接表,超内存了: 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <string.h> 5 using namespace std; 6 const int N=10002; 7 const i

ZOJ 2587 Unique Attack 判断最小割是否唯一

很裸的判断最小割是否唯一.判断方法是先做一遍最大流求最小割,然后从源点和汇点分别遍历所有能够到达的点,看是否覆盖了所有的点,如果覆盖了所有的点,那就是唯一的,否则就是不唯一的. #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostr