题目链接HDU1879
http://acm.hdu.edu.cn/showproblem.php?pid=1879
题解
状态是1的两个分量直接联通,然后套模板。
#
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<string>
#include<cctype>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 1e+9
int pa[10000];
int ranke[10000];
int find(int x)
{
if(x!=pa[x])
{
pa[x]=find(pa[x]);
}
return pa[x];
}
void unin(int x,int y)
{
int a=find(x);int b=find(y);
if(a==b)return ;
if(ranke[a]>ranke[b])
{
pa[b]=a;
}
else
{
pa[a]=b;
if(ranke[a]==ranke[b])ranke[b]++;
}
}
typedef struct qz
{
int u,v,cost;
int flag;
};
bool cmp(const qz &a,qz &b)
{
return a.cost<b.cost;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{ qz s[7000];
memset(pa,0,sizeof(pa));
memset(ranke,0,sizeof(ranke));
if(n==0)break;
int m=n*(n-1)/2;
for(int i=0;i<m;i++)
{
pa[i]=i;
ranke[i]=0;
}
for(int i=0;i<m;i++)
{
int aa,bb,cc,dd;
scanf("%d%d%d%d",&aa,&bb,&cc,&dd);
if(dd==1)
{
s[i].u=aa;
s[i].v=bb;
s[i].cost=cc;
s[i].flag=1;
unin(find(aa),find(bb));
}
else
{
s[i].u=aa;
s[i].v=bb;
s[i].cost=cc;
s[i].flag=0;
}
}
sort(s,s+m,cmp);
int res=0;
int countt=0;
for(int i=0;i<m;i++)
{ qz e=s[i];
if(flag==0) {
if(find(e.u)!=find(e.v))
{unin(find(e.u),find(e.v));
res+=e.cost;
}
}
}
printf("%d\n",res);
}
return 0;
}
题目链接HDU1875
http://acm.hdu.edu.cn/showproblem.php?pid=1875
题解
算出每两个岛之间的距离,判断一下,然后再用模板。
代码
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<string>
#include<cctype>
#include<algorithm>
#include<vector>
using namespace std;
int pa[10000];
int ranke[10000];
int find(int x)
{
if(x!=pa[x])
pa[x]=find(pa[x]);
return pa[x];
}
void unin(int x,int y)
{
int a=find(x);
int b=find(y);
if(a==b)return ;
if(ranke[a]>ranke[b])pa[b]=a;
else{
pa[a]=b;
if(ranke[a]==ranke[b])ranke[b]++;
}
}
typedef struct qz{
int u,v;
double cost;
};
bool cmp(const qz& a,const qz &b)
{
return a.cost<b.cost;
}
int a[10000];
int b[10000];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
vector<qz>s;
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){pa[i]=i;ranke[i]=0;}
for(int i=0;i<n;i++){scanf("%d%d",&a[i],&b[i]);}
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
double z=fabs(sqrt(pow(a[j]-a[i],2)+pow(b[j]-b[i],2)));
if(z>=10.0&&z<=1000.0)
{
qz e;
e.v=i;
e.u=j;
e.cost=z;
s.push_back(e);
}
}
}
sort(s.begin(),s.end(),cmp);
int countt=0;
double ans=0.0;
for(int i=0;i<s.size();i++)
{ qz e=s[i];
if(find(e.v)!=find(e.u))
{
unin(e.v,e.u);
ans+=e.cost;
countt++;
if(countt==n-1)break;
}
}
if(countt==n-1)printf("%.1lf\n",ans*100);
else printf("oh!\n");
}
return 0;
}
题目链接HDU2682
http://acm.hdu.edu.cn/showproblem.php?pid=2682
题解
方法如上,先打出素数表,然后依次求得距离,特么的要注意,1不是素数…
代码
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<string>
#include<cctype>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=2000005;
int a[maxn];
void prime()
{
memset(a,0,sizeof(a));
a[0]=1;
a[1]=1;
// a[2]=1;
for(int i=2;i<=maxn;i++)
{
if(a[i]==0)
{
for(int j=i*2;j<=maxn;j+=i)a[j]=1;
}
}
}
int pa[200000];
int ranke[200000];
int find(int x)
{
if(x!=pa[x])
pa[x]=find(pa[x]);
return pa[x];
}
void unin(int x,int y)
{
int a=find(x);
int b=find(y);
if(a==b)return ;
if(ranke[a]>ranke[b])pa[b]=a;
else{
pa[a]=b;
if(ranke[a]==ranke[b])ranke[b]++;
}
}
typedef struct qz{
int u,v;
int cost;
};
bool cmp(const qz& a,const qz &b)
{
return a.cost<b.cost;
}
int dd[370000];
int main()
{
int t;
scanf("%d",&t);
prime();
while(t--)
{ for(int i=0;i<200000;i++){pa[i]=i;ranke[i]=0;}
int n;
memset(dd,0,sizeof(dd));
scanf("%d",&n);
vector<qz>s;
for(int i=1;i<=n;i++)scanf("%d",&dd[i]);
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(a[dd[i]]==0||a[dd[j]]==0||a[abs(dd[i]+dd[j])]==0)
{
qz e;
e.u=i;
e.v=j;
e.cost=min(dd[i],min(dd[j],abs(dd[i]-dd[j])));
s.push_back(e);
}
}
}
sort(s.begin(),s.end(),cmp);
int countt=0;
long long res=0;
for(int i=0;i<s.size();i++)
{
qz e=s[i];
int c=e.v;
int cc=e.u;
if(find(e.v)!=find(e.u))
{
unin(e.v,e.u);
res+=(long long)e.cost;
countt++;
if(countt==n-1)break;
}
}
if(countt==n-1)printf("%lld\n",res);
else printf("-1\n");
}
return 0;
}