poj1679+uva10600+uva10462 次小生成树
这三货是一套的,改改输入输出
注意在判断次小生成树时,要保证最后用到的边的总数为n-1,否则非法.
---
前两道wa了好久,一直放着,直到今天打开uva10462才意识到题目保证最小生成树存在但没保证次小生成树一定存在..
Poj 1679
#include <iostream> #include <math.h> #include <string.h> #include <vector> #include <map> #include <queue> #include <stdio.h> #include <algorithm> #include <cstdio> using namespace std; int fa[500000],cnt=0,a[500000],head[500000]; struct lys{ int from,to,cost,next; }edge[20000]; void add(int from,int to,int cost) { cnt++; edge[cnt].from=from; edge[cnt].to=to; edge[cnt].cost=cost; edge[cnt].next=head[from]; head[from]=cnt; } int find(int x) { if(fa[x]!=x) { fa[x]=find(fa[x]); } return fa[x]; } bool cmp(lys a,lys b) { return a.cost<b.cost; } int main() { // freopen("lys.in","r",stdin); int t,n,m; cin>>t; for(int i=1;i<=t;i++) { cnt=0; memset(a,0,sizeof(a)); memset(head,0,sizeof(head)); scanf("%d%d",&n,&m); for(int j=1;j<=m;j++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); } sort(edge+1,edge+cnt+1,cmp); for(int j=1;j<=n;j++) fa[j]=j; int ans=0,count=0; for(int j=1;j<=cnt;j++) { int f1=find(edge[j].from),fb=find(edge[j].to); if(f1!=fb) { count++; a[count]=j; ans+=edge[j].cost; fa[f1]=fb; } } int minn=20211030; for(int j=1;j<=count;j++) //枚举该次不用的边 { int ans2=0,use=0; for(int k=1;k<=n;k++) fa[k]=k; for(int k=1;k<=cnt;k++) { if(k==a[j]) continue; int f1=find(edge[k].from),f2=find(edge[k].to); if(f1!=f2) { use++; fa[f1]=f2; ans2+=edge[k].cost; } } if(use==n-1) minn=min(minn,ans2); } if(minn==ans) { printf("Not Unique!\n"); } else cout<<ans<<endl; } }
Uva 10600
#include <iostream> #include <math.h> #include <string.h> #include <vector> #include <map> #include <queue> #include <stdio.h> #include <algorithm> #include <cstdio> using namespace std; int fa[500000],cnt=0,a[500000],head[500000]; struct lys{ int from,to,cost,next; }edge[20000]; void add(int from,int to,int cost) { cnt++; edge[cnt].from=from; edge[cnt].to=to; edge[cnt].cost=cost; edge[cnt].next=head[from]; head[from]=cnt; } int find(int x) { if(fa[x]!=x) { fa[x]=find(fa[x]); } return fa[x]; } bool cmp(lys a,lys b) { return a.cost<b.cost; } int main() { //freopen("lys.in","r",stdin); int t,n,m; cin>>t; for(int i=1;i<=t;i++) { cnt=0; memset(a,0,sizeof(a)); memset(head,0,sizeof(head)); scanf("%d%d",&n,&m); for(int j=1;j<=m;j++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); } sort(edge+1,edge+cnt+1,cmp); for(int j=1;j<=n;j++) fa[j]=j; int ans=0,count=0; for(int j=1;j<=cnt;j++) { int f1=find(edge[j].from),fb=find(edge[j].to); if(f1!=fb) { count++; a[count]=j; ans+=edge[j].cost; fa[f1]=fb; } } int minn=20211030; for(int j=1;j<=count;j++) //枚举该次不用的边 { int ans2=0,use=0; for(int k=1;k<=n;k++) fa[k]=k; for(int k=1;k<=cnt;k++) { if(k==a[j]) continue; int f1=find(edge[k].from),f2=find(edge[k].to); if(f1!=f2) { use++; fa[f1]=f2; ans2+=edge[k].cost; } } if(use==n-1) minn=min(minn,ans2); } cout<<ans<<" "<<minn<<endl; } }
Uva 10462
#include <iostream> #include <math.h> #include <string.h> #include <vector> #include <map> #include <queue> #include <stdio.h> #include <algorithm> #include <cstdio> using namespace std; int fa[500000],cnt=0,a[500000],head[500000]; struct lys{ int from,to,cost,next; }edge[20000]; void add(int from,int to,int cost) { cnt++; edge[cnt].from=from; edge[cnt].to=to; edge[cnt].cost=cost; edge[cnt].next=head[from]; head[from]=cnt; } int find(int x) { if(fa[x]!=x) { fa[x]=find(fa[x]); } return fa[x]; } bool cmp(lys a,lys b) { return a.cost<b.cost; } int main() { int t,n,m; cin>>t; for(int i=1;i<=t;i++) { cnt=0; memset(a,0,sizeof(a)); memset(head,0,sizeof(head)); scanf("%d%d",&n,&m); for(int j=1;j<=m;j++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); } sort(edge+1,edge+cnt+1,cmp); for(int j=1;j<=n;j++) fa[j]=j; int ans=0,count=0; for(int j=1;j<=cnt;j++) { int f1=find(edge[j].from),fb=find(edge[j].to); if(f1!=fb) { count++; a[count]=j; ans+=edge[j].cost; fa[f1]=fb; } } if(count<n-1) { printf("Case #%d : No way\n",i); continue; } int minn=20211030; for(int j=1;j<=count;j++) //枚举该次不用的边 { int ans2=0,use=0; for(int k=1;k<=n;k++) fa[k]=k; for(int k=1;k<=cnt;k++) { if(k==a[j]) continue; int f1=find(edge[k].from),f2=find(edge[k].to); if(f1!=f2) { use++; fa[f1]=f2; ans2+=edge[k].cost; } } if(use==n-1) minn=min(minn,ans2); } if(minn==20211030) { printf("Case #%d : No second way\n",i); continue; } else { printf("Case #%d : %d\n",i,minn); } } }