hdu3938(并查集+离线)

来源:互联网 发布:气象局和环保局知乎 编辑:程序博客网 时间:2024/05/22 15:36

这道题的第一个难点在于题目,对于我等英语菜B来说,理解这个题意还真是有点难......

理解了题意之后,可以发现,用最小生成树的思路理解,如果可以加入某一条边使两个集合联通,那么增加的路径个数就是num【a】×num【b】。

所以我第一次写的代码如下:



#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#define N 10005using namespace std;int G[N],num[N];struct len{    int a,b,leng;}Len[5*N];int findx(int x){    return G[x]==x?x:G[x]=findx(G[x]);}bool cmp(len a,len b){    return a.leng<b.leng;}int main(){    int n,m,q,ans;    while(scanf("%d %d %d",&n,&m,&q)!=EOF)    {        int i,answer,j;        for(i=0;i<m;i++)        {            scanf("%d %d %d",&Len[i].a,&Len[i].b,&Len[i].leng);        }        sort(Len,Len+m,cmp);        for(i=0;i<q;i++)        {            scanf("%d",&ans);            j=0,answer=0;            for(j=0;j<=n;j++) G[j]=j,num[j]=1;            j=0;            while(Len[j].leng<=ans && j!=m)            {                int p=findx(Len[j].a),                    q=findx(Len[j].b);                if(p!=q)                {                    G[p]=q;                    answer+=(num[q]*num[p]);                    num[q]+=num[p];                }                j++;            }            printf("%d\n",answer);        }    }    return 0;}

提交了之后发现TLE了,经查看样例发现,有一部分的数据重复计算,增加了时间的损耗,所以我可以先记录,排序,后计算,由此:计算时间就变成了最大的那个数的计算时间,提交了AC


#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#define N 10005using namespace std;int G[N],num[N],ans1[N];struct len{    int a,b,leng;}Len[5*N];struct ans{    int a,i;}answer[N];int findx(int x){    return G[x]==x?x:G[x]=findx(G[x]);}bool cmp(len a,len b){    return a.leng<b.leng;}bool cmp2(ans a,ans b){    return a.a<b.a;}int main(){    int n,m,q,ans;    while(scanf("%d %d %d",&n,&m,&q)!=EOF)    {        int i,answer1,j;        for(i=0;i<m;i++)        {            scanf("%d %d %d",&Len[i].a,&Len[i].b,&Len[i].leng);        }        for(i=0;i<q;i++)        {            scanf("%d",&answer[i].a);            answer[i].i=i;        }        sort(Len,Len+m,cmp);        sort(answer,answer+q,cmp2);        for(j=0;j<=n;j++) G[j]=j,num[j]=1;        j=0,answer1=0;        for(i=0;i<q;i++)        {            while(Len[j].leng<=answer[i].a && j!=m)            {                int p=findx(Len[j].a),                    q=findx(Len[j].b);                if(p!=q)                {                    G[p]=q;                    answer1+=(num[q]*num[p]);                    num[q]+=num[p];                }                j++;            }            ans1[answer[i].i]=answer1;        }        for(i=0;i<q;i++)        {            printf("%d\n",ans1[i]);        }    }    return 0;}


0 0
原创粉丝点击