例题一: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;
}