标签:des style blog color java 使用 os io
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9941 Accepted Submission(s): 2827
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 long
using 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;
}
图论 --- 最小生成树 + 剪枝 + 路径合并,布布扣,bubuko.com
标签:des style blog color java 使用 os io
原文地址:http://www.cnblogs.com/acmer-jsb/p/3898339.html