题意:给你n m k; 最小生成树的经典输入,k的意思代表给定有k条路已经连通了。现在要你求出连通所有路的最小价值
思路:最小生成树的变形,只要用并查集把已经连通的点放到一起就可以了,再最小生成树算法
AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,cnt;
int f[520];
int flag[520];
#define N 25005
struct node
{
int u,v,w;
}num[N];
bool cmp(node x,node y)
{
return x.w<y.w;
}
int find(int x)
{
if(x!=f[x])
f[x]=find(f[x]);
return f[x];
}
int kruscal()
{
int x,y,i;
//int dian=n;
int sum=0;
for(i=0;i<cnt;i++)
{
x=find(num[i].u);
y=find(num[i].v);
if(x==y)
continue;
sum+=num[i].w;
f[x]=y;
flag[num[i].u]=1;
flag[num[i].v]=1;
/* dian--;
if(dian==0)
break;*/
}
/* if(i==cnt)
return -1;*/
// else
return sum;
}
int main()
{
int k,i,j,sum;
int t;
scanf("%d",&t);
while(t--)
{
cnt=0;
scanf("%d %d %d",&n,&m,&k);
memset(flag,0,sizeof(int)*(n+2));
for(i=0;i<=n;i++)
f[i]=i;
for(i=0;i<m;i++)
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
num[cnt].u=a;
num[cnt].v=b;
num[cnt++].w=c;
}
sort(num,num+cnt,cmp);
for(i=0;i<k;i++)
{
int a,b;
int test;
scanf("%d",&test);
scanf("%d",&a);
flag[a]=1;
for(j=1;j<test;j++)
{
scanf("%d",&b);
flag[b]=1;
int x=find(a);
int y=find(b);
if(x!=y)
f[x]=y;
}
}
sum=kruscal();
for(i=1;i<=n;i++)
if(!flag[i])
break;
if(i<=n)
printf("-1
");
else
printf("%d
",sum);
}
return 0;
}
上一篇 Linq 访问数据库
下一篇 Oracle EBS创建LPN