Tour Belt [UVALive 4848] 并查集+枚举边长

    技术2022-05-20  36

    题目要求:

           求出满足以下两个条件的子图数:

           1.子图定点数大于等于2

           2.子图中的所有边都大于(所有子图外的(与子图中的点有公共点的的边的长))

    题解:

       将边的长度离散化,从大到小枚举边长,每次统计最小边边长为枚举的边长的子图,累加即可.

    /*  * File:   main.cpp  * Author: swordholy  *  * Created on 2011年3月1日, 上午8:56  */ #include <cstdlib> #include <list> #include <iostream> #include <stdio.h> #include <memory.h> #include <iterator> #include <algorithm> using namespace std; int n,m; #define MAXM 250005 #define MAXN 5005 struct edge {     int s,t,l;     bool operator <(const edge &rhs) const     {         if (l<rhs.l) return true;         else return false;     } }; edge e[MAXM]; list<int> LK[MAXN]; list<int>::iterator ita,itb; int father[MAXN]; int ans; int me[MAXN],ee[MAXN]; bool cnt[5005][5005]; int cha(int x) {     if (x!=father[x])         father[x]=cha(father[x]);     return father[x]; } void bing(int a,int b) {     int i,j;     a=cha(a);     b=cha(b);     if (a==b) {ee[a]++;return ;}     father[b]=a;     ee[a]+=ee[b]+1;     me[a]+=me[b];     for(ita=LK[a].begin();ita!=LK[a].end();ita++)         for(itb=LK[b].begin();itb!=LK[b].end();itb++)         {             me[a]+=cnt[(*ita)][(*itb)];         }     LK[a].merge(LK[b]); } int calced[MAXN]; void calc_ans(int i) {     int a;     a=cha(e[i].s);     if (calced[a]==e[i].l) return ;     if ( (ee[a]==me[a])&&(calced[a]!=e[i].l) )     {         ans+=LK[a].size();         calced[a]=e[i].l;     } } int main(int argc, char** argv) {     int i,j,t,u,x,y,z;     cin>>t;     for(u=1;u<=t;u++)     {         cin>>n>>m;         memset(cnt,0,sizeof(cnt));         for(i=1;i<=m;i++)         {             cin>>e[i].s>>e[i].t>>e[i].l;             cnt[e[i].s][e[i].t]=cnt[e[i].t][e[i].s]=1;         }         sort(e+1,e+m+1);         e[0].l=-1;         ans=0;         memset(me,0,sizeof(me));         memset(ee,0,sizeof(ee));         memset(calced,-1,sizeof(calced));         for(i=1;i<=n;i++)         {             father[i]=i;             LK[i].clear();             LK[i].push_back(i);         }         int lasti=m+1,ii;         for(i=m;i>=1;i--)         {             if (e[i].l==e[i-1].l)             {                 bing(e[i].s,e[i].t);             }             else             {                 bing(e[i].s,e[i].t);                 for(ii=i;ii<lasti;ii++)                 calc_ans(ii);                 lasti=i;             }         }         cout<<ans<<endl;     }     return 0; }


    最新回复(0)