杭电3371——————MST的简单变形

来源:互联网 发布:网络十大神曲 编辑:程序博客网 时间:2024/06/15 08:55

Connect the Cities

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10598    Accepted Submission(s): 3008


Problem Description
In 2100, since the sea level rise, most of the cities disappear. Though some survived cities are 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 money.  
 

Input
The first line contains the number of test cases.
Each test case 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 <= 100) stands for the number of still connected cities.
To make it easy, the cities are signed from 1 to n.
Then follow m lines, each contains three integers p, q and c (0 <= c <= 1000), means it takes c to connect p and q.
Then follow k lines, each line starts with an integer t (2 <= t <= n) stands for the number of this connected cities. Then t integers follow stands for the id of these cities.
 

Output
For each case, output the least money you need to take, if it’s impossible, just output -1.
 

Sample Input
16 4 31 4 22 6 12 3 53 4 332 1 22 1 33 4 5 6
 

Sample Output
1
题意很简单,就是告诉你在城市之间建立道路所需要的费用,和一些已经连通的城市,问最小的费用下让所有城市连通。

这个题目我当时看了没什么思路,现在想想真是傻逼到不行了=_=,特别简单,已经连通的费用就定为0,从剩下的尚未连通的城市直接prim就行了!

(这个题本来是不值得写的,没什么意思其实。之前好像做过一个类似的,但是就是这么不长记性!警示自己!)

有一点点需要注意的地方就是什么时候输出-1.

这个其实很简单,如果你在剩余城市结点中寻找的时候mindist没有被更新,此时表明是不连通了。(详见代码)

AC :(484MS)

<span style="font-size:14px;">#include <stdio.h>#include <string.h>#define maxn 505#define INF 0xffffffint G[maxn][maxn];int intree[maxn];int city[maxn];void Init(){for(int i = 0 ; i < maxn ; ++i)for(int j = 0 ;j < maxn ; ++j)G[i][j] = INF;memset(intree,0,sizeof(intree));memset(city,0,sizeof(city));}void Prim(int N){int mindist[maxn] = {0};//mindist表示结点1到其他结点的最小距离int node,dist;int sum = 0;bool flag = true;for(int i = 1 ; i <= N ; ++i)mindist[i] = G[1][i];intree[1] = 1;for(int nodenum = 1 ; nodenum < N ; ++nodenum) // 已经有1个结点在A集合中,还剩下N-1个结点,即查询N-1次{dist = INF;for(int i = 1 ; i <= N ; ++i){if(!intree[i] && mindist[i] < dist){dist = mindist[i];node = i;}}if(dist == INF){flag = false;break;}intree[node] = 1;sum += dist;for(int i = 1 ; i <= N ; ++i)if(!intree[i] && mindist[i] > G[node][i])mindist[i] = G[node][i];}if(!flag)printf("%d\n",-1);elseprintf("%d\n",sum);}int main(){int test;int N,M,K,T;int v1,v2,value;scanf("%d",&test);while(test--){Init();scanf("%d%d%d",&N,&M,&K);while(M--){scanf("%d%d%d",&v1,&v2,&value);if(G[v1][v2] > value)//考虑重边问题 G[v1][v2] = G[v2][v1] = value;}while(K--){scanf("%d",&T);for(int i = 1 ; i <= T ; ++i)scanf("%d",&city[i]);for(int i = 1 ; i <= T ; ++i)for(int j = 1 ; j <= T ; ++j)G[city[i]][city[j]] = 0;//已经连通了就不用花费钱去建造了 }Prim(N);}return 0;}</span>



0 0
原创粉丝点击