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 }

posted on 2012-05-16 19:52  myoi  阅读(329)  评论(0编辑  收藏  举报

导航