HDU 5441 Travel(最短路径变形)

来源:互联网 发布:视频放大的软件 编辑:程序博客网 时间:2024/06/17 19:54
/*题意:有一个n个点的无向图,给出m条边的边权,给出q次询问,每次给出一个值,求用到所有边权不大于这个值的边的情况下,能够互相到达的点对的个数(自己到自己不算)分析:先把路线按照权值从小到大排序,然后再把那几个值按从小到大排序。后面就是一系列最短路径问题了,貌似不难*/#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxm=1e5;int n,m,k;int num[maxm];int p[maxm];int ans[maxm];void Init(){    for(int i=0;i<=maxm;i++)    {        p[i]=i;        num[i]=1;    }}struct node{    int u,v,c;    bool operator<(const node &s)const    {        return c<s.c;    }}t[maxm];struct NODE{    int w,id;    bool operator<(const NODE &p)const    {        return w<p.w;    }}T[maxm];int find(int k){    if(p[k]!=k)    {        return p[k]=find(p[k]);    }    else    {        return p[k];    }}int main(){    int y;    scanf("%d",&y);    while(y--)    {        Init();        memset(ans,0,sizeof(ans));        scanf("%d%d%d",&n,&m,&k);        for(int i=0;i<m;i++)        {            scanf("%d%d%d",&t[i].u,&t[i].v,&t[i].c);        }        sort(t,t+m);        for(int i=0;i<k;i++)        {            scanf("%d",&T[i].w);            T[i].id=i;        }        sort(T,T+k);        int j=0;        int cnt=0;        for(int i=0;i<k;i++)        {            while(j<m&&t[j].c<=T[i].w)            {                int x=find(t[j].u);                int y=find(t[j].v);                j++;                if(x!=y)                {                    p[x]=y;                    cnt+=(num[x]*num[y]);                    num[y]+=num[x];                }            }            ans[T[i].id]=2*cnt;        }        for(int i=0;i<k;i++)        {            printf("%d\n",ans[i]);        }    }    return 0;}

0 0
原创粉丝点击