標籤:des style blog color java 使用 os io
Connect the Cities
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9941 Accepted Submission(s): 2827
Problem DescriptionIn 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.
InputThe 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.
OutputFor each case, output the least money you 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
Mean:
好久沒刷水題了。。。
給你一個有向圖,其中某些邊是串連的,現在要你找一棵最小產生樹。
analyse:
先用並查集來合并已經連通的邊,然後在使用kruskal來求最小產生樹,注意這兒有一個剪枝,因為這題的邊很多,所以我們不需要全部判斷,根據最小產生樹的性質可知,我們只需要找出n-1條邊即可。
Time complexity:O(n)
Source code:
//Memory Time// 5644K 241MS//by : Snarl_jsb#include<algorithm>#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<vector>#include<queue>#include<stack>#include<iomanip>#include<string>#include<climits>#include<cmath>#define MAXV 520#define MAXE 25010#define LL long longusing namespace std;int T,n,m,k;struct Node{ int s,e,val;} graph[MAXE];int father[MAXV];void scan(int& x){ x = 0; char c = getchar (); while (!(c>=‘0‘ && c<=‘9‘ || c==‘-‘)) c = getchar (); while (c >= ‘0‘ && c <= ‘9‘){ x = x * 10 + c - ‘0‘; c = getchar (); }}int Find(int x){ return x==father[x]?x:father[x]=Find(father[x]);}bool cmp(Node a,Node b){ return a.val<b.val;}int kruskal(){ int ans=0; int cnt=0; sort(graph+1,graph+1+m,cmp); for(int i=1;i<=n;i++) if(father[i]==i) cnt++; for(int i=1;i<=m&&cnt>1;i++) { int x=Find(graph[i].s); int y=Find(graph[i].e); if(x!=y) { father[x]=y; ans+=graph[i].val; cnt--; } } if(cnt==1) return ans; else return -1;}int main(){// freopen("cin.txt","r",stdin);// freopen("cout.txt","w",stdout); scan(T); while(T--) { scan(n); scan(m); scan(k); for(int i=1;i<=m;i++) { scan(graph[i].s); scan(graph[i].e); scan(graph[i].val); } for(int i=0;i<=n;i++) father[i]=i; int cnt,fa,son; while(k--) { scan(cnt); scan(fa); fa=Find(fa); while(--cnt) { scan(son); father[Find(son)]=fa; } } int mincost=kruskal(); printf("%d\n",mincost); } return 0;}