POJ - 1287 Networking (prim)
题意:给出N台电脑(编号为1~N),然后M条连接路径以及对应权值,问怎样把所有结点连接且使得权值和最小
思路:这就是一道最小生成树。但是要注意的是,在输入中,会出现某条边重复输入且权值不同的情况,那么我们就要对应的 add中进行更新判断
完整代码:
#include <iostream> #include <cstring> #include <cstdio> #include <queue> #include <vector> #include <algorithm> using namespace std; const int maxn = 1000; const int maxm = 1e5; int n,m; int ans; typedef pair<int,int> pii; struct Egde{ int u,v,w,next; }edge[maxm]; struct cmp{ bool operator () (pii a, pii b){ return a.first > b.first; } }; int head[maxn]; int vis[maxn]; int dist[maxn]; int top; void init(){ memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); memset(dist,-1,sizeof(dist)); top = 0; ans = 0; } void add(int u,int v,int w){ int i;//更新最小边权值 for(i=head[u]; ~i; i=edge[i].next){ if(edge[i].v == v){ if(edge[i].w > w) edge[i].w = w; return ; } } edge[top].u = u; edge[top].v = v; edge[top].w = w; edge[top].next = head[u]; head[u] = top++; } void prim(int s){ int i; priority_queue<pii,vector<pii>, cmp>q; vis[s] = 1; dist[s] = 0; for(i = head[s];~i;i = edge[i].next){ int v = edge[i].v; dist[v] = edge[i].w; q.push(make_pair(dist[v],v)); } while(!q.empty()){ pii t = q.top(); q.pop(); if(vis[t.second]) continue; ans += t.first; vis[t.second] = 1; for(i = head[t.second]; ~i;i = edge[i].next){ int v = edge[i].v; if(!vis[v]&&(dist[v]>edge[i].w)||dist[v] == -1){ dist[v] = edge[i].w; q.push(make_pair(dist[v],v)); } } } } int main(){ while(cin>>n&&n){ cin>>m; init(); int a,b,c; if(!m) {cout<<0<<endl; continue;} for(int i=0;i<m;i++){ cin>>a>>b>>c; add(a,b,c); add(b,a,c); } prim(1); cout<<ans<<endl; } }