poj1679+uva10600+uva10462 次小生成樹
阿新 • • 發佈:2021-10-30
這三貨是一套的,改改輸入輸出
注意在判斷次小生成樹時,要保證最後用到的邊的總數為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); } } }