码迷,mamicode.com
首页 > 其他好文 > 详细

hdu3938 Portal 离线的并查集

时间:2014-08-22 23:48:09      阅读:343      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   ar   art   

  离线算法是将全部输入都读入,计算出所有的答案以后再输出的方法。主要是为避免重复计算。类似于计算斐波那契数列的时候用打表的方法。

  题目:给一个无向图,求有多少个点对,使得两点间的路径上的花费小于L,这里路径上的花费是这样规定的,a、b两点之间所有的路径中的最大边的最小值。   
  当然题目上不是这么写的。它问的是有多少种路径,这里就比较模糊了,到底两个路径怎样才算是两种路径呢,这时候重新看题,可以发现,如果理解为路径中经过的点不同的话,题目中给的所谓两点间的花费这个定义就没有意义了,所以就可以猜测,题目要求的是有多少个点对了。
然后就明确题意后,再进行分析。对一个点对的所有路径,只要最短最大边的那条路径出现,其后的所有较大最大边的路径都是毫无意义的,那么不妨将所有的边按照权值从小对大进行排序,用并查集的方法,进行加边,已经连通的点就不再管。那么每次加边的时候,是将两个集合并在一起的过程,假设集合大小分为a,b,显然路径的种类是a*b个,此时对于所有大于集合中最大边的L,都要加上这个种类数了。

  那么,算法就明确了,为离线算法,先输入所有的边和L,对所有的L进行排序,对所有的边进行排序,都为从小到大,然后对每个L,将比其小的边权的边都并在一起,计算种类数即可。

  上面的两段来源于:http://blog.csdn.net/sdj222555/article/details/7439187

  有点感慨,如果没有读懂题目,真的无法做题。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=10010,M=50010;
struct node
{
    int u,v,w;
}edge[M];
bool cmp(const node &a, const node &b)
{
    return a.w<b.w;
}
int f[N],r[N];
int n,m,q,cnt;
void init()
{
    for(int i=0;i<=n;i++)
    {
        f[i]=i;r[i]=1;
    }
}
int Find(int x)
{
    if(x==f[x])  return x;
    return f[x]=Find(f[x]);
}
void Link(int x,int y)
{
    int a=Find(x), b=Find(y);
    cnt=0;
    if(a!=b)
    {
        f[b]=a;
        cnt=r[a]*r[b];
        r[a]+=r[b];
    }
}
int ans[N];
struct NODE
{
    int id,re,num;
}que[N];
bool cmp1(const NODE &a,const NODE &b)
{
    return a.num<b.num;
}
bool cmp2(const NODE &a,const NODE &b)
{
    return a.id<b.id;
}
int main()
{
    //freopen("test.txt","r",stdin);
    int i,j,k;
    while(scanf("%d%d%d",&n,&m,&q)!=EOF)
    {
        init();
        for(i=0;i<m;i++)
            scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
        for(i=0;i<q;i++)
        {
            scanf("%d",&que[i].num);
            que[i].id=i;
            que[i].re=0;
        }
        sort(edge,edge+m,cmp);
        sort(que,que+q,cmp1);
        k=0;
        for(i=0;i<q;i++)
        {
            while(edge[k].w<=que[i].num&&k<m)
            {
                int a=Find(edge[k].u), b=Find(edge[k].v);
                if(a==b) {k++; continue;}
                else
                {
                    Link(edge[k].u,edge[k].v);
                    que[i].re+=cnt;
                    k++;
                }
            }
            if(i>0) que[i].re+=que[i-1].re;
        }
        sort(que,que+q,cmp2);
        for(i=0;i<q;i++)
            printf("%d\n",que[i].re);
    }
    return 0;
}

 

hdu3938 Portal 离线的并查集

标签:style   blog   http   color   os   io   for   ar   art   

原文地址:http://www.cnblogs.com/Potato-lover/p/3930375.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!