ural 1416 Confidential 次小生成树

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

思路:http://www.cppblog.com/MatoNo1/archive/2011/05/29/147627.aspx

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<cstdio>
  5 #include<vector>
  6 #include<algorithm>
  7 using namespace std;
  8 #define MAXM 300010
  9 #define MAXN 100010
 10 #define INF (~0u>>2)
 11 int n,m,top=0;
 12 struct Edge
 13 {
 14     int x,y,w;
 15 };
 16 struct node
 17 {
 18     int num,weight,id;
 19     node *next;
 20 };
 21 node *graph[MAXN];
 22 node memo[2*MAXM];
 23 Edge edge[MAXM];
 24 vector<int> p[MAXN];
 25 int l[MAXN];
 26 int f[MAXN];
 27 int edge_num=0;
 28 int ans=0,minn=INF;
 29 void add(int x,int y,int w,int id)
 30 {
 31     node *p=&memo[top++];
 32     p->num=y; p->weight=w; p->id=id; p->next=graph[x]; graph[x]=p;
 33     p=&memo[top++]; 
 34     p->num=x; p->weight=w; p->id=id; p->next=graph[y]; graph[y]=p;
 35 }
 36 
 37 int find(int x)
 38 {
 39     return f[x]==-1? x:f[x]=find(f[x]);
 40 }
 41 
 42 void merge(int x,int y)
 43 {
 44     int fx=find(x),fy=find(y);
 45     f[fx]=fy;
 46     l[fy]+=l[fx];
 47     for(int i=0;i<l[fx];i++)
 48         p[fy].push_back(p[fx][i]);
 49 }
 50 bool cmp(const Edge &x,const Edge &y)
 51 {
 52     return x.w<y.w;
 53 }
 54 void Kruskal()
 55 {
 56     int i,u,v,j,father_u,father_v;
 57     for(i=1;i<=m;i++)
 58     {
 59         u=edge[i].x; v=edge[i].y;
 60         if(find(u)==find(v)) continue;
 61         edge_num++;
 62         ans+=edge[i].w;
 63         father_u=find(u); father_v=find(v);
 64         if(l[father_u]>l[father_v]) swap(father_u,father_v);
 65         //cout<<i<<" "<<father_u<<" "<<father_v<<" "<<l[father_u]<<" "<<l[father_v]<<endl;
 66         for(j=0;j<l[father_u];j++)
 67         {
 68             u=p[father_u][j];
 69             for(node *p=graph[u];p;p=p->next)
 70             {
 71                 if(find(p->num)==father_v&&p->id!=i)
 72                     minn=min(minn,p->weight-edge[i].w);
 73             }
 74         }
 75         merge(father_u,father_v);
 76     }
 77 }
 78 int main()
 79 {
 80     memset(graph,0,sizeof(graph));
 81     memset(f,0xff,sizeof(f));
 82     scanf("%d%d",&n,&m);
 83     int i;
 84     for(i=1;i<=m;i++)
 85         scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].w);
 86     sort(edge+1,edge+m+1,cmp);
 87     for(i=1;i<=m;i++)
 88         add(edge[i].x,edge[i].y,edge[i].w,i);
 89     for(i=1;i<=n;i++)
 90         p[i].push_back(i),l[i]=1;
 91     Kruskal();
 92     if(edge_num<n-1)
 93         printf("Cost: -1\nCost: -1\n");
 94     else if(minn==INF)
 95         printf("Cost: %d\nCost: -1\n",ans);
 96     else
 97         printf("Cost: %d\nCost: %d\n",ans,ans+minn);
 98 
 99     return 0;
100 }
原文地址:https://www.cnblogs.com/myoi/p/2498184.html