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 }