题目:点击打开链接
题意:
分析:
就是给一个图,求最小生成树。
prime算法:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
const int N=50;
int g[N][N],dis[N];
char op[2];
int n;
bool vis[N];
int prim(int src)
{
for(int i=0;i<n;i++){
dis[i]=g[src][i];
}
memset(vis,0,sizeof(vis));
vis[src]=1;
int res=0;
int p;
for(int i=1;i<n;i++){
int tmp=0x3f3f3f3f;
for(int j=0;j<n;j++){
if(!vis[j]&&dis[j]<tmp){
tmp=dis[j];
p=j;
}
}
//if(tmp==0x3f3f3f3f)break;
res+=tmp;
vis[p]=1;
for(int j=0;j<n;j++){
if(!vis[j]&&dis[j]>g[p][j])dis[j]=g[p][j];
}
}
return res;
}
int main()
{
while(~scanf("%d",&n)&&n){
int num,w;
memset(g,0x3f,sizeof(g));
for(int i=1;i<n;i++){
scanf("%s%d",op,&num);
int u=op[0]-'A';
while(num--){
scanf("%s%d",op,&w);
int v=op[0]-'A';
if(w<g[u][v])
g[u][v]=g[v][u]=w;
}
}
printf("%d\n",prim(0));
}
}
priority_queue优化的prime算法,但是数据有点弱,跟上面都是0ms,没太大区别。
我觉得,这种方法之于prime,就像spfa之于dijkstra,思想都是一致的,只是实现不同而已。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
const int N=50;
#define MP(x,y) make_pair(x,y)
typedef pair<int,int>pii;
vector<pii>e[N];
bool vis[30];
int dis[30];
int n;
int prim(int src)
{
priority_queue<pii,vector<pii>,greater<pii> >q;
memset(vis,0,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
int res=0;
dis[src]=0;
q.push(MP(0,src));
while(!q.empty()){
pii t=q.top();
q.pop();
int u=t.second;
if(!vis[u]){
vis[u]=1;
res+=dis[u];
for(int i=0;i<e[u].size();i++){
int v=e[u][i].second;
int w=e[u][i].first;
if(!vis[v]&&dis[v]>w){
dis[v]=w;
q.push(MP(w,v));
}
}
}
}
return res;
}
int main()
{
// freopen("f.txt","r",stdin);
char op[2];
while(~scanf("%d",&n)&&n){
int num,w;
for(int i=0;i<n;i++)e[i].clear();
for(int i=1;i<n;i++){
scanf("%s%d",op,&num);
int u=op[0]-'A';
while(num--){
scanf("%s%d",op,&w);
int v=op[0]-'A';
e[u].push_back(MP(w,v)),e[v].push_back(MP(w,u));
}
}
printf("%d\n",prim(0));
}
return 0;
}
Kruskal算法:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
const int N=50;
struct edge
{
int u,v,w;
edge(){}
edge(int u,int v,int w):u(u),v(v),w(w){}
bool operator < (const edge &a)const{
return w<a.w;
}
}e[100];
int fa[N];
int n;
int findfa(int x)
{
return fa[x]!=x?fa[x]=findfa(fa[x]):x;
}
int Kruskal(int edgenum)
{
sort(e,e+edgenum);
for(int i=0;i<n;i++)fa[i]=i;
int ans=0;
for(int i=0;i<edgenum;i++){
int u=findfa(e[i].u),v=findfa(e[i].v);
if(u!=v){
fa[u]=v;
ans+=e[i].w;
}
}
return ans;
}
int main()
{
// freopen("f.txt","r",stdin);
char op[2];
while(~scanf("%d",&n)&&n){
int num,w;
int cnt=0;
// for(int i=0;i<n;i++)e[i].clear();
for(int i=1;i<n;i++){
scanf("%s%d",op,&num);
int u=op[0]-'A';
while(num--){
scanf("%s%d",op,&w);
int v=op[0]-'A';
e[cnt++]=edge(u,v,w);
}
}
printf("%d\n",Kruskal(cnt));
}
return 0;
}