poj 1639

来源:互联网 发布:皖都金融网络贷款 编辑:程序博客网 时间:2024/06/08 12:14


详细解法请看这里: Click

vo度最大为k的最小生成树

#include <cstdio>#include <iostream>#include <string>#include <cmath>#include <cstring>#include <algorithm>#include <cstring>#include <vector>#include <map>using namespace std;const int inf = 0x3f3f3f3f;const int N = 1111;int n,k;map<string,int> name;vector<string> vec;int g[N][N],vis[N];int li[N][N],lowcost[N],pre[N];int kk,ans;struct node{int u,v,len;node(){}node(int _u,int _v,int _del):u(_u),v(_v),len(_del){}}del[N];void prim(int u){for(int i = 1;i < n;i++){lowcost[i] = g[u][i];pre[i] = u;}vis[u] = true;while(true){int pr = -1 , mind = inf;for(int i = 1;i < n;i++)if(!vis[i] && lowcost[i] < mind){mind = lowcost[i];pr = i;}if(pr == -1) break;ans += mind;li[pre[pr]][pr] = li[pr][pre[pr]] = 1;if(g[0][kk] > g[0][pr]) kk = pr;vis[pr] = true;for(int i = 1;i < n;i++)if(!vis[i] && lowcost[i] > g[pr][i])lowcost[i] = g[pr][i] , pre[i] = pr;}}void dfs(int u,int fa,int del_u,int del_v){for(int i = 1;i < n;i++){if(li[u][i] && i!=fa){if(fa == -1 || g[del_u][del_v] < g[u][i]){del[i] = node(u,i,g[u][i]);dfs(i,u,u,i);}else{del[i] = node(del_u,del_v,g[del_u][del_v]);dfs(i,u,del_u,del_v);}}}}void solve(){memset(vis,0,sizeof(vis));memset(li,0,sizeof(li));ans = 0;vis[0] = true;for(int i = 1;i < n;i++){if(vis[i]) continue;kk = i;k--;prim(i);li[0][kk] = li[kk][0] = 1;ans += g[0][kk];dfs(kk,-1,-1,-1);}memset(vis,0,sizeof(vis));while(k--){int c = 0 , todel = -1;for(int i = 1;i < n;i++){if(li[0][i] || g[0][i] == inf) continue;if(c > g[0][i] - del[i].len){c = g[0][i] - del[i].len;todel = i;}}if(c == 0) break;ans += c;li[0][todel] = li[todel][0] = 1;li[del[todel].u][del[todel].v]=li[del[todel].v][del[todel].u] = 0;dfs(todel, 0 , -1,-1);}printf("Total miles driven: %d\n",ans);}int getNum(const string &s){if(name.count(s) > 0)return name[s];vec.push_back(s);return name[s] = vec.size()-1;} void init(){memset(g,0x3f,sizeof(g));name.clear();vec.clear();getNum("Park");string su,sv;for(int i = 0,w;i < n;i++){cin >> su >> sv;cin >> w;int u = getNum(su) ,v = getNum(sv);if(g[u][v] > w)g[u][v] = g[v][u] = w;}n = vec.size();//for(int i = 0;i < n;i++){//for(int j = 0;j < n;j++)//printf("g[%d][%d]=%d ",i,j,g[i][j]);//printf("\n");//}scanf("%d",&k);}int main(){while(scanf("%d",&n)!=EOF){init();solve();}return 0;}


0 0
原创粉丝点击