BNUOJ-26586 Simon the Spider 最小生成树+枚举

  题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=26586

  题意:给一个图,每条边有一个权值。要你求选择一棵树,权值和为sum,然后在树上选择一条边权值为w,然后使得sum-2*w最小。

  首先求一遍最小生成树,然后求出每两个点之间的最小瓶颈路,然后枚举边就行了。。  

  1 //STATUS:C++_AC_916MS_30048KB
  2 #include <cmath>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <iostream>
  6 #include <algorithm>
  7 using namespace std;
  8 #define mem(a,b) memset(a,b,sizeof(a))
  9 typedef long long LL;
 10 
 11 const int N=2010;
 12 
 13 struct Edge{
 14     int u,v,w;
 15 }e[1000010],et[2000010];
 16 int first[N],next[2000010];
 17 int p[N],vis[N],d[N][N];
 18 bool mst[1000010];
 19 int n,m,mt;
 20 
 21 void adde(int a,int b,int c)
 22 {
 23     et[mt].u=a,et[mt].v=b,et[mt].w=c;
 24     next[mt]=first[a];first[a]=mt++;
 25     et[mt].u=b,et[mt].v=a,et[mt].w=c;
 26     next[mt]=first[b];first[b]=mt++;
 27 }
 28 
 29 int cmp(const Edge& a,const Edge& b)
 30 {
 31     return a.w<b.w;
 32 }
 33 
 34 int find(int x){return p[x]==x?x:p[x]=find(p[x]);}
 35 
 36 int Kruskal()
 37 {
 38     int i,j,x,y,sum=0,cnt=0;
 39     for(i=1;i<=n;i++)p[i]=i;
 40     sort(e,e+m,cmp);
 41     mem(mst,0);
 42     for(i=0;i<m;i++){
 43         x=find(e[i].u);
 44         y=find(e[i].v);
 45         if(x!=y){
 46             cnt++;
 47             sum+=e[i].w;
 48             p[y]=x;
 49             mst[i]=true;
 50         }
 51     }
 52     if(cnt<n-1)return -1;
 53     return sum;
 54 }
 55 
 56 int dfs(int& s,int u,int fa,int hig)
 57 {
 58     int i,v;
 59     for(i=first[u];i!=-1;i=next[i]){
 60         v=et[i].v;
 61         if(v==fa)continue;
 62         d[s][v]=max(hig,et[i].w);
 63         dfs(s,v,u,d[s][v]);
 64     }
 65     return 0;
 66 }
 67 
 68 int main(){
 69  //   freopen("in.txt","r",stdin);
 70     int i,j;
 71     while(~scanf("%d%d",&n,&m))
 72     {
 73         for(i=0;i<m;i++){
 74             scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
 75         }
 76 
 77         int sum;
 78         if((sum=Kruskal())==-1){
 79             printf("disconnected\n");
 80             continue;
 81         }
 82         mem(first,-1);mt=0;
 83         for(i=0;i<m;i++){
 84             if(mst[i]){
 85                 adde(e[i].u,e[i].v,e[i].w);
 86             }
 87         }
 88         mem(d,0);
 89         for(i=1;i<=n;i++){
 90             dfs(i,i,-1,0);
 91         }
 92         int ans=0x7FFFFFFF;
 93         for(i=0;i<m;i++){
 94             ans=min(ans,sum-d[e[i].u][e[i].v]-e[i].w);
 95         }
 96 
 97         printf("%d\n",ans);
 98     }
 99     return 0;
100 }

 

posted @ 2013-08-27 02:45  zhsl  阅读(305)  评论(0编辑  收藏  举报