题意:
一些点已经连通,还有一些未连通,求所有的点连通,需要的代价。
题解:
最小生成树模板题,先根据邻接矩阵把边都存起来,然后把已经相邻的边权为0,再存起来。跑一遍kk,这些边权为0的肯定把刚才邻接表存进去的给覆盖(用不到他们)了!
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<string>
#include<cstring>
#include<vector>
#include<functional>
#include<utility>
#include<set>
#include<map>
#include<cmath>
#include<cctype>
using namespace std;
const int maxn=105;
struct edge
{
int u,v,cost;
edge(int u,int v,int d):u(u),v(v),cost(d){}
bool operator<(const edge& a)const
{
return cost<a.cost;
}
};
vector<edge>es;
int pa[maxn];
int n;
int findset(int x){return pa[x]<0?x:pa[x]=findset(pa[x]);}
int kk()
{
sort(es.begin(),es.end());
memset(pa,-1,sizeof(pa));
int cnt=0,sum=0;
for(int i=0;i<es.size();i++)
{
int u=es[i].u, v=es[i].v;
if(findset(u)!=findset(v))
{
pa[findset(u)]=findset(v);
sum+=es[i].cost;
if(++cnt>=n-1)break;
}
}
return sum;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
int x;cin>>x;
if(i<j)es.push_back(edge(i,j,x));
}
int q;
cin>>q;
while(q--)
{
int u,v;
cin>>u>>v;
u--;v--;
es.push_back(edge(u,v,0));
}
cout<<kk()<<endl;
}