單身晚會
Time Limit: 1000 MS | Memory Limit: 65536 KB |
Total Submissions: 53 | Accepted: 16 |
Description
但是,ZJ的好基友們想到以後ZJ就不能經常跟他們一起愉快的玩耍了,都覺得非常傷心難過,於是他們決定在最後一晚爲ZJ開一場單身晚會,玩整晚緊張刺激的飛行棋。
ZJ的好基友居住在城市的各個地方(每個地方不一定只有一個基友),他們需要從各個地方趕到其中一個朋友的家裏來參加這最後的單身PARTY,ZJ被基友們的熱情深深感動了,決定對基友們來時的路費進行報銷。報銷規則按照距離來計算。基友們爲了幫ZJ省錢,決定在所有人走最短路徑的情況下,總距離最小的人的家裏開PARTY。
ZJ想知道基友們走過的總距離是多少,然後他把總共需要報銷的錢拿出來,就可以讓基友們自己來分配了。但是他算了半天也沒算出來總距離是多少,單身PARTY馬上就開始了,你能幫幫他嗎?
Input
每組數據的第一行基友數(包括ZJ)N(N<100),路口P(2<=P<=100),路口之間道路數C(1<=C<=1450),(基友的編號爲1…N,路口的編號爲1…P)
第二行到第N+1行:編號爲1到N的基友們家所在的路口號。
第N+2行到N+C+1行:每行有三個數:相連的路口A,B,路口間間距D(1<=D<=255),當然,連接是雙向的。
Output
Sample Input
3 4 5
2
3
4
1 2 1
1 3 5
2 3 7
2 4 3
3 4 5
Sample Output
Hint
選擇一個路口(不一定要有人住),使所有人到這個路口的路程和最小化
這題應該是省賽現場修改題意,但這裏用的是原題意,特此說明。對被卡的同學再次表示歉意。對其他題目有疑義的可以發信件給賬號instankill詢問。
#include <iostream>
#include <cstdio>
#include <cstring>
typedef long long LL;
const LL INF = 1000000000;
using namespace std;
int a[101];
LL L[101][101];
int n, p, c;
void floyd() //Floyd最短路徑算法
{
for (int k=1; k<=p; k++)
for (int i=1; i<=p; i++)
for (int j=1; j<=p; j++)
L[i][j] = min(L[i][j], L[i][k]+L[k][j]);
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d%d%d", &n, &p, &c);
for (int i=1; i<=n; i++)
scanf("%d", &a[i]);
int A, B, D;
for (int i=1; i<=p; i++)
for (int j=1; j<=p; j++)
L[i][j] = INF;
for (int i=1; i<=p; i++)
L[i][i] = 0;
for (int i=0; i<c; i++) {
scanf("%d%d%d", &A, &B, &D);
L[A][B] = D;
L[B][A] = D;
}
floyd();
LL Smin = INF, s = 0;
for (int i=1; i<=p; i++) {
s = 0;
for (int j=1; j<=n; j++) {
if (L[i][a[j]] >= INF) //先排除無窮大的邊
goto to; //出現就進入下一次循環
s += L[i][a[j]];
}
Smin = min(Smin, s); //求出每次的最短路徑
to:;
}
printf("%d\n", Smin);
}
return 0;
}