Topic:
Connect the Cities |
Time limit:2000/1000 MS (java/others) Memory limit:32768/32768 K (java/others) |
Total submission (s): 391 Accepted Submission (s): 139 |
|
problem DescriptionIn 2100, since the sea level rise, Most of the cities disappear. Though Some survived cities is still connected with others, but most of them become disconnected. The government wants to build some roads to connect all of these cities again, but they don't want to take too much. |
Inputthe First line contains the number of test cases. Each test case is starts with three integers:n, M and K. N (3 <= n <=500) stands for the number of survived cities, m (0 <= M <= 25000) stands for the number of roads you can choose to connect the cities and K (0 <= K <=) St ANDs for the number of still connected cities. To make it easy, the cities is signed from 1 to N. Then follow m lines, each contains three integers p, Q and C (0 <= C <=), means it takes C to connect P and Q. Then follow k lines, each line starts with a integer t (2 <= t <= N) stands for the number of this connected cities . Then T integers follow stands for the ID of these cities.
|
Outputfor each case, the output of the least money is need to take, if it's impossible, just output-1. |
Sample Input16 4 31 4 22 6 12 3 53 4 332 1 22 1 33 4 5 6 |
Sample Output1 |
Authordandelion |
Sourcehdoj Monthly contest–2010.04.04 |
Recommendlcy |
Topic Analysis:
To find the minimum spanning tree. This problem uses kruscal to do the tle. After all, kruscal is suitable for sparse graphs, this problem may be a little more. Then use prim to do, in C + + submitted can be AC (Hangzhou electric Server feel recently is not a bit ...) The same code for the first time is tle (>1000ms), the second turn on the 493ms, which is not a little bit worse. It's going to crash. )。
It is important to note that this question is about the input data format for "Built Road":
For example, in the sample:
16 4 31 4 22 6 12 3 53 4 332 1 22 1 33 4 5 6
Starting with "2 1 2" is the data of the road that has been built. It means that the road between Point 1 and point 2 has been built. The back means that point 1 and point 3 have been built,
In the back, point 4 is connected to point 5 and point 6.
The code is as follows:
/* * g1.cpp * * Created on:2015 March 10 * author:administrator * * #include <iostream> #include <cstdio> #in Clude <string>using namespace Std;const int maxn = 501;const int inf = 999999;int Map[maxn][maxn];bool p[maxn];int d Is[maxn];int pre[maxn];int N;int Prim () {int sum = 0;int i;for (i = 2; I <= n; ++i) {p[i] = false;dis[i] = map[1][i];p re [I] = 1;} DIS[1] = 0;p[1] = true;pre[1] = 1;for (i = 1; I <= n-1; ++i) {int min = inf;int k = 0;int j;for (j = 1; j <= N; ++j {if (!p[j] && dis[j] < min) {//dis[j] = Min;min = Dis[j];k = j;}} if (k = = 0) {//no point can be extended, graph is not connected, unable to find minimum spanning tree return-1;//direct return-1.} Sum + = Dis[k];p [k] = true;for (j = 1; j <= N; ++j) {if (!p[j] && dis[j] > Map[k][j]) {dis[j] = Map[k][j];p re[j ] = k;}}} return sum;} int main () {int t;scanf ("%d", &t), int tmp[maxn];while (t--) {int m,k;scanf ("%d%d%d", &n,&m,&k); int i,j; for (i = 1, i <= N; ++i) {for (j = 1; j <= N; ++j) {if (i = = j) {Map[i][j] = 0;} ELSE{MAP[I][J] = inf;}}} for (i = 1 ; I <= m; ++i) {int a,b,c;scanf ("%d%d%d", &a,&b,&c), if (Map[a][b] > C) {map[a][b] = map[b][a] = c;}} The processing of data for a road that has been built. (Note that the previous topic gives a different form) for (i = 1; I <= K; ++i) {int size;scanf ("%d", &size);//int tmp[size];for (j = 0; J < siz E ++J) {scanf ("%d", &tmp[j]);} for (j = 0; j < size-1; ++j) {map[tmp[j]][tmp[j+1]] = 0;map[tmp[j+1]][tmp[j]] = 0;}} printf ("%d\n", Prim ()),//printf ("%d\n", Prim1 ());} return 0;}
Here is the version of Tle made with kruscal:
/* * g.cpp * * Created on:2015 March 10 * author:administrator * * #include <iostream> #include <cstdio> #inc Lude <algorithm> #include <vector>using namespace std;const int maxn = 505;struct Edge{int begin;int end;int We ight;} Edges[maxn*maxn];int father[maxn];int n;int Find (int a) {if (a = = Father[a]) {return A;} return Father[a] = find (Father[a]);} int kruscal (int count) {int i;for (i = 1; I <= n; ++i) {father[i] = i;} int counter = 0;int sum = 0;for (i = 1; I <= count; ++i) {if (counter = = n-1) {break;} int fa = Find (edges[i].begin), int fb = find (Edges[i].end), if (FA! = FB) {FATHER[FA] = fb;sum + = edges[i].weight;counter++;} }//printf ("%d\n", counter); return sum;} BOOL CMP (Edge A,edge b) {return a.weight < b.weight;} int main () {int t;scanf ("%d", &t), int tmp[maxn];while (t--) {int m,k;scanf ("%d%d%d", &n,&m,&k); int cnt = 1 ; int i;for (i = 1; I <= m; ++i) {scanf ("%d%d%d", &edges[cnt].begin,&edges[cnt].end,&edges[cnt++].weight);} for (i = 1; i <= k; ++i) {int size;scanf ("%d", &size),//int tmp[size];//vector<int> tmp;int j;for (j = 0; j < size; ++j) {scanf ("%d", &tmp[j]);} for (j = 0; j < size-1; ++j) {edges[cnt].begin = Tmp[j];edges[cnt].end = Tmp[j+1];edges[cnt++].weight = 0;}} CNT-= 1;sort (edges+1,edges+1+cnt,cmp);p rintf ("%d\n", Kruscal (CNT));} return 0;}
If you are not familiar with the prim algorithm can take this problem practice. It is a bare topic that asks for the smallest spanning tree:
http://www.sdutacm.org/sdutoj/problem.php?action=showproblem&problemid=2144
The AC code for this problem is:
/* * t.cpp * * Created on:2015 March 10 * author:administrator * * #include <iostream> #include <cstdio> #inc Lude <cstring>using namespace Std;const int maxn = 101;const int inf = 99999;int map[maxn][maxn];bool p[maxn];int di S[maxn];int pre[maxn];int N,m;int Prim () {int sum = 0;int i;for (i = 2; I <= n; ++i) {p[i] = false;dis[i] = Map[1][i];p r E[i] = 1;} P[1] = true;dis[1] = 0;for (i = 1; I <= n-1; ++i) {int min = inf;int k = 0;int j;for (j = 1; j <= N; ++j) {if (!p[j] && Dis[j] < min) {min = Dis[j];k = j;}} if (k = = 0) {return-10;} Sum + = Dis[k];p [k] = true;for (j = 1; j <= N; ++j) {if (!p[j] && dis[j] > Map[k][j]) {dis[j] = Map[k][j];p re[j ] = k;}}} return sum;} int main () {while (scanf ("%d%d", &n,&m)!=eof) {//memset (map,inf,sizeof (map)); memset (P,false,sizeof (P)); int I ; int j;for (i = 1; I <= n; ++i) {for (j = 1; j <= N; ++j) {if (i = = j) {Map[i][j] = 0;} ELSE{MAP[I][J] = inf;}}} for (i = 1; I <= m; ++i) {int a,b,c;scanf ("%d%d%d", &a, &b,&c), if (Map[a][b] > C) {map[a][b] = map[b][a] = c;}} printf ("%d\n", Prim ());} return 0;}
(Hdu step 6.1.7) Connect the Cities (the minimum cost of N-point connectivity in the case where some roads have been built)