用并查集合并集合时,不能直接
p[net[t][i]]=net[t][1];
而要
int u=net[t][i];
int v=net[t][1];
int xx=find(u);
int yy=find(v);
if(xx!=yy) p[xx]=yy;
附上代码
#include<stdio.h>
#include<vector>
#include<algorithm>
#define maxn 1010
using namespace std;
int n,q;
vector<int>net[10];
vector<int>cho;
int x[maxn],y[maxn],p[maxn];
int Pow[10];
int ans;
int find(int x){return p[x]==x?x:p[x]=find(p[x]);}
struct Edge
{
int u,v;
int dis;
Edge(int a,int b,int c):u(a),v(b),dis(c){}
bool operator < (const Edge& rhs) const
{
return dis<rhs.dis;
}
};
vector<Edge>edges;
int dis(int i,int j)
{
int xx=x[i]-x[j];
int yy=y[i]-y[j];
return xx*xx+yy*yy;
}
void init()
{
for(int i=0;i<10;i++) net[i].clear();
edges.clear();
cho.clear();
ans=0;
for(int i=1;i<maxn;i++) p[i]=i;
}
void get()
{
scanf("%d %d",&n,&q);
for(int i=0;i<q;i++)
{
int num,sum,temp;
scanf("%d %d",&num,&sum);
net[i].push_back(sum);
while(num--)
{
scanf("%d",&temp);
net[i].push_back(temp);
}
}
for(int i=1;i<=n;i++) scanf("%d %d",&x[i],&y[i]);
}
void pre()
{
for(int i=1;i<=n;i++)
for(int j=1;j<i;j++)
edges.push_back(Edge(i,j,dis(i,j)));
sort(edges.begin(),edges.end());
for(unsigned int i=0;i<edges.size();i++)
{
int xx=find(edges[i].u);
int yy=find(edges[i].v);
if(xx!=yy) {ans+=edges[i].dis;p[xx]=yy;cho.push_back(i);}
}
}
int ADD(int t)
{
for(unsigned int i=2;i<net[t].size();i++)
{
int u=net[t][i];
int v=net[t][1];
int xx=find(u);
int yy=find(v);
if(xx!=yy) p[xx]=yy;
}
return net[t][0];
}
int INIT(int aaa)
{
int ANS=0;
for(int i=1;i<=n;i++) p[i]=i;
for(int i=0;i<q;i++)
{
int bbb=(aaa>>i)&1;
if(bbb) ANS+=ADD(i);
}
return ANS;
}
void solve()
{
int ANS;
for(int i=1;i<Pow[q];i++)
{
ANS=INIT(i);
for(unsigned int j=0;j<cho.size();j++)
{
int e=cho[j];
int xx=find(edges[e].u);
int yy=find(edges[e].v);
if(xx!=yy){ANS+=edges[e].dis;p[xx]=yy;}
}
ans=min(ANS,ans);
}
printf("%d\n",ans);
}
int main()
{
Pow[0]=1;
for(int i=1;i<10;i++) Pow[i]=Pow[i-1]*2;
int t;
scanf("%d",&t);
while(t--)
{
init();
get();
pre();
solve();
if(t) puts("");
}
return 0;
}