zoukankan      html  css  js  c++  java
  • bjoi 2010 次小生成树

    题意:求无向图的严格次小生成树

    思路:综合前两篇文章

    http://www.cnblogs.com/myoi/archive/2012/05/13/2498184.html

    http://www.cnblogs.com/myoi/archive/2012/05/14/2500371.html

      1 //严格
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<cstdio>
      6 #include<vector>
      7 #include<algorithm>
      8 using namespace std;
      9 #define MAXM 300010
     10 #define MAXN 100010
     11 #define INF 987654321
     12 long long n,m,top=0;
     13 struct Edge
     14 {
     15     long long x,y,w;
     16 };
     17 struct node
     18 {
     19     long long num,weight,id;
     20     node *next;
     21 };
     22 pair<long long,long long> max_edge[MAXN];
     23 pair<long long,long long> ans[MAXM];
     24 vector<pair<long long,long long> > query[2*MAXM];
     25 vector<long long> que[MAXM];
     26 bool used[MAXM],use[MAXN];    
     27 node *graph[MAXN];
     28 node memo[2*MAXM];
     29 Edge edge[MAXM];
     30 long long f[MAXN],father[MAXN],root;
     31 long long Ans=0,minn=INF;
     32 void add(long long x,long long y,long long w,long long id)
     33 {
     34     node *p=&memo[top++];
     35     p->num=y; p->weight=w; p->id=id; p->next=graph[x]; graph[x]=p;
     36     p=&memo[top++]; 
     37     p->num=x; p->weight=w; p->id=id; p->next=graph[y]; graph[y]=p;
     38 }
     39 
     40 long long find(long long x)
     41 {
     42     if(f[x]==-1) return x;
     43     long long root=find(f[x]);
     44     if(max_edge[x].first<max_edge[f[x]].first)
     45     {
     46         long long temp1=max_edge[f[x]].first;
     47         long long temp2=max(max_edge[x].first,max_edge[f[x]].second);
     48         max_edge[x]=make_pair(temp1,temp2);
     49     }
     50     else if(max_edge[x].first==max_edge[f[x]].first)
     51     {
     52         long long temp1=max_edge[f[x]].first;
     53         long long temp2=max(max_edge[x].second,max_edge[f[x]].second);
     54         max_edge[x]=make_pair(temp1,temp2);
     55     }
     56     else
     57     {
     58         long long temp1=max_edge[x].first;
     59         long long temp2=max(max_edge[f[x]].first,max_edge[x].second);
     60         max_edge[x]=make_pair(temp1,temp2);
     61     }
     62     f[x]=root;
     63     return root;
     64 }
     65 void merge(long long x,long long y)
     66 {
     67     long long fx=find(x),fy=find(y);
     68     if(fx!=fy)
     69     f[fx]=fy;
     70 }
     71 
     72 
     73 bool cmp(const Edge &x,const Edge &y)
     74 {
     75     return x.w<y.w;
     76 }
     77 void Kruskal()
     78 {
     79     long long i,u,v,j;
     80     for(i=1;i<=m;i++)
     81     {
     82         u=edge[i].x; v=edge[i].y;
     83         if(find(u)==find(v)) continue;
     84         add(edge[i].x,edge[i].y,edge[i].w,i);
     85         Ans+=edge[i].w;
     86         root=edge[i].x;
     87         used[i]=1;
     88         merge(u,v);
     89     }
     90 }
     91 void dfs(long long u)
     92 {
     93     max_edge[u].first=max_edge[u].second=-INF;
     94     for(node *p=graph[u];p;p=p->next)
     95     if(p->num!=father[u])
     96     {
     97         father[p->num]=u;
     98         dfs(p->num);
     99         max_edge[p->num].first=p->weight;
    100         max_edge[p->num].second=-INF;
    101         merge(p->num,u);
    102     }
    103     use[u]=1;
    104     vector<pair<long long,long long> >:: iterator i;
    105     long long j;
    106     for(i=query[u].begin();i!=query[u].end();i++)
    107         if(use[i->first])
    108             que[find(i->first)].push_back(i->second); 
    109     for(j=0;j<que[u].size();j++)
    110     {
    111         find(edge[que[u][j]].x); find(edge[que[u][j]].y);
    112         if(max_edge[edge[que[u][j]].x].first<max_edge[edge[que[u][j]].y].first)
    113         {
    114             ans[que[u][j]].first=max_edge[edge[que[u][j]].y].first;
    115             ans[que[u][j]].second=max(max_edge[edge[que[u][j]].x].first,max_edge[edge[que[u][j]].y].second);
    116         }
    117         else if(max_edge[edge[que[u][j]].x].first==max_edge[edge[que[u][j]].y].first)
    118         {
    119             ans[que[u][j]].first=max_edge[edge[que[u][j]].y].first;
    120             ans[que[u][j]].second=max(max_edge[edge[que[u][j]].x].second,max_edge[edge[que[u][j]].y].second);
    121         }
    122         else
    123         {
    124             ans[que[u][j]].first=max_edge[edge[que[u][j]].x].first;
    125             ans[que[u][j]].second=max(max_edge[edge[que[u][j]].y].first,max_edge[edge[que[u][j]].x].second);
    126         }
    127     }
    128 }
    129     
    130 void solve()
    131 {
    132     memset(use,0,sizeof(use));
    133     memset(f,0xff,sizeof(f));
    134     long long i;
    135     for(i=1;i<=m;i++)
    136     if(!used[i])
    137     {
    138         query[edge[i].x].push_back(make_pair(edge[i].y,i));
    139         query[edge[i].y].push_back(make_pair(edge[i].x,i));
    140     }
    141     
    142     father[root]=0;
    143     dfs(root);
    144     for(i=1;i<=m;i++)
    145     if(!used[i])
    146     {
    147         if(ans[i].first==edge[i].w)
    148             minn=min(edge[i].w-ans[i].second,minn);
    149         else 
    150             minn=min(edge[i].w-ans[i].first,minn);
    151     }
    152     printf("%lld\n",Ans+minn);
    153 }
    154 
    155 
    156 int main()
    157 {
    158     memset(used,0,sizeof(used));
    159     memset(graph,0,sizeof(graph));
    160     memset(f,0xff,sizeof(f));
    161     scanf("%lld%lld",&n,&m);
    162     long long i;
    163     Ans=0;
    164     for(i=1;i<=m;i++)
    165         scanf("%lld%lld%lld",&edge[i].x,&edge[i].y,&edge[i].w);
    166     sort(edge+1,edge+m+1,cmp);
    167     Kruskal();
    168     solve();
    169     return 0;
    170 }
  • 相关阅读:
    php 时间问题
    php语言
    高级查询
    数据库的查询详情
    数据库的创建和增删改查,外键和主键的创建
    数据库
    js的基本语句和语法
    JS的脚本语言
    样式、格式布局
    表单的元素和样式表
  • 原文地址:https://www.cnblogs.com/myoi/p/2505341.html
Copyright © 2011-2022 走看看