例题一:http://acm.hdu.edu.cn/showproblem.php?pid=1879
AC代码:
#include<iostream>//c++ #include<cmath>//数学公式 #include<cstdlib>//malloc #include<cstring> #include<string> #include<cstdio>//输入输出 #include<algorithm>//快排 #include<queue>//队列 #include<functional>//优先队列 #include<stack>//栈 #include<vector>//容器 #include<map>//地图 if continue typedef long long ll; const int N=10+100; const int inf=0x7fffffff; using namespace std; int w[N],n; typedef struct{ int a,b,c; }G;G g; struct cmp{ bool operator() (G x ,G y) { return x.c>y.c; } }; priority_queue<G ,vector<G> ,cmp >q; void liantong(int a,int b) { int c=w[a]; for(int i=1;i<=n;i++) if(c==w[i]) w[i]=w[b]; } int main() { //freopen("C:\\Users\\ch\\Desktop\\1.txt","r",stdin); //freopen("C:\\Users\\lenovo\\Desktop\\2.txt","w",stdout); int i,j,k; int a,b,c,d; while(scanf("%d",&n),n) { while(!q.empty()) q.pop(); int m=n-1; int ans=0; for(i=1;i<=n;i++) w[i]=i; for(i=0;i<(n-1)*n/2;i++) { scanf("%d%d%d%d",&a,&b,&c,&d); if(d) liantong(a,b),--m; else {g.a=a;g.b=b;g.c=c;q.push(g);} } while(m>0) { g=q.top(); q.pop(); if(w[g.a]==w[g.b]) continue; ans+=g.c; liantong(g.a,g.b); m--; } // cout<<ans<<endl; printf("%d\n",ans); } return 0; }
例题二:http://acm.hdu.edu.cn/showproblem.php?pid=1863
AC代码:
#include<iostream>//c++ #include<cmath>//数学公式 #include<cstdlib>//malloc #include<cstring> #include<string> #include<cstdio>//输入输出 #include<algorithm>//快排 #include<queue>//队列 #include<functional>//优先队列 #include<stack>//栈 #include<vector>//容器 #include<map>//地图 if continue typedef long long ll; const int N=10+100; const int inf=0x7fffffff; using namespace std; int w[N],n; typedef struct{ int a,b,c; }G;G g; struct cmp{ bool operator() (G x ,G y) { return x.c>y.c; } }; priority_queue<G ,vector<G> ,cmp >q; void liantong(int a,int b) { int c=w[a]; for(int i=1;i<=n;i++) if(c==w[i]) w[i]=w[b]; } int main() { //freopen("C:\\Users\\ch\\Desktop\\1.txt","r",stdin); //freopen("C:\\Users\\lenovo\\Desktop\\2.txt","w",stdout); int i,j,k; int a,b,c,d; while(scanf("%d%d",&d,&n),d) { while(!q.empty()) q.pop(); int m=n-1; int ans=0; for(i=1;i<=n;i++) w[i]=i; for(i=0;i<d;i++) { scanf("%d%d%d",&g.a,&g.b,&g.c); q.push(g); } while(m>0&&!q.empty()) { g=q.top(); q.pop(); if(w[g.a]==w[g.b]) continue; ans+=g.c; liantong(g.a,g.b); m--; } if(m>0) printf("?\n"); else printf("%d\n",ans); } return 0; }
http://acm.fzu.edu.cn/problem.php?pid=2087
(有多少边至少存在一个最小生成树里面)
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int maxn=100005; const int maxm=100005; int n,m; int parent[maxn]; struct Node { int from,to,w; }node[maxm]; void init(int n) { for(int i=1;i<=n;i++) parent[i]=i; } int find(int x) { if(parent[x]==x) return x; else return parent[x]=find(parent[x]); } bool same(int x,int y) { return find(x)==find(y); } void unite(int x,int y) { parent[find(x)]=find(y); } bool cmp(Node a,Node b) { return a.w<b.w; } void solve() { int cnt=0; int i,j; for(i=1;i<=m;i=j) { for(j=i;node[j].w==node[i].w;j++)//只要相同权值的边两个端点不在同一个集合,该边就一定存在一个最小生成树里面 { if(!same(node[j].from,node[j].to)) cnt++; } for(j=i;node[j].w==node[i].w;j++)//有回路的边加上不影响后面的加边 unite(node[j].from,node[j].to); } printf("%d\n",cnt); } int main() { int t;scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); init(n); for(int i=1;i<=m;i++) scanf("%d%d%d",&node[i].from,&node[i].to,&node[i].w); sort(node+1,node+1+m,cmp); solve(); } return 0; }