超级传送门:
http://acm.hdu.edu.cn/showproblem.php?pid=1863
题目大意:
就是给一个图各个边的大小,求最小生成树,没什么特别
题目分析:
既然没什么特别就,当做练习,不再拷贝模板,手敲。。
一手敲还是出现很多问题的:
居然define 错误写成 #define inf = 900000000; 居然出现两个错
头文件忘记包含queue,vector,两个都不要忘了
while(visited[edge.v] != 0 && !pq.empty() ); 这里也曾经敲错了,而且,答案居然还是正确的,交上去就超时,要谨慎!
明天再拿其他题目再敲敲。。。
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
#define inf 900000000
const int MAXN = 120;
struct XEdge
{
int v; //边端点
int w; //边权值
XEdge(int v_ = 0, int w_ = inf):v(v_),w(w_) { }
};
vector < vector<XEdge> > G(MAXN);
operator < (const XEdge e1,const XEdge e2)
{
return e1.w > e2.w;
}
int HeapPrim(const vector< vector <XEdge> > G , int n)
{
int i;
XEdge edge(1,0);
priority_queue<XEdge> pq;
vector<int> dis(MAXN);
vector<int> visited(MAXN);
int nDone = 0;
int ans = 0;
//初始化
for(i=1;i<=n;i++)
{
dis[i] = inf;
visited[i] = 0;
}
pq.push(edge);
//找最短边,
while(nDone < n && !pq.empty())
{
do
{
edge = pq.top();
pq.pop();
}while(visited[edge.v] != 0 && !pq.empty() );
if(visited[edge.v] == 0)
{
//找到一条最短的边,加进最小生成树中
ans += edge.w;
visited[edge.v] = 1;
nDone++;
//修改
for(i=0;i<G[edge.v].size();i++)
{
int k = G[edge.v][i].v;
if(visited[k] == 0)
{
if(dis[k] > G[edge.v][i].w)
{
dis[k] = G[edge.v][i].w;
pq.push(XEdge(k,dis[k]));
}
}
}
}
}
if(nDone < n)
{
return -1;
}
else
{
return ans;
}
}
int main()
{
int N,M;
int a,b,c;
int i;
int sum;
while(scanf("%d",&N) != EOF)
{
if(N == 0) break;
scanf("%d",&M);
for(i=0;i<N;i++)
{
scanf("%d %d %d",&a,&b,&c);
G[a].push_back(XEdge(b,c));
G[b].push_back(XEdge(a,c));
}
sum = HeapPrim(G,M);
if(sum == -1)
{
printf("?\n");
}
else
{
printf("%d\n",sum);
}
G.clear();
G.resize(MAXN);
}
return 0;
}