生成树
来源:互联网 发布:qq的网络传输协议 编辑:程序博客网 时间:2024/06/07 11:36
POJ 1639 最小度限制生成树 http://poj.org/problem?id=1639
#include<cstdio>#include<iostream>#include<cstring>#include<cstdlib>#include<cmath>#include<ctype.h>#include<algorithm>#include<stack>#include<queue>using namespace std;#define maxn 22int n,k;int e1[maxn][maxn];int e2[maxn][maxn];struct Edge{ int u,v,w; Edge(int a,int b,int c){u=a,v=b,w=c;} bool friend operator< (Edge a,Edge b){ return a.w>b.w; }};priority_queue<Edge> q;char name[maxn][12];int l;char s1[12],s2[12];int get_id(char *p){ for(int i=0;i<l;i++){ if(strcmp(p,name[i])==0) return i; } strcpy(name[l],p); l++; return l-1;}int bin[maxn];int find(int a){ if(bin[a]!=a) bin[a]=find(bin[a]); return bin[a];}bool get(int a,int b){ int x=find(a); int y=find(b); if(x!=y) {bin[y]=x;return 1;} return 0;}void dfs(int u,int fa){ for(int i=1;i<l;i++){ if(e2[u][i]==1&&i!=fa){ get(u,i); dfs(i,u); } }}void Print_ans(){ int ans=0; for(int i=0;i<l;i++) for(int j=i+1;j<l;j++) if(e2[i][j]==1) ans+=e1[i][j]; printf("Total miles driven: %d\n",ans);}void solve(){ int cnt=0; for(int i=0;i<=l;i++) bin[i]=i; while(!q.empty()){ Edge e=q.top(); q.pop(); if(get(e.u,e.v)){ if(e.u==0||e.v==0) cnt++; e2[e.u][e.v]=e2[e.v][e.u]=1; } } for(int i=0;i<=l;i++) bin[i]=i; for(int j=1;j<l;j++){ if(e2[0][j]==1) dfs(j,0); } while(cnt>k){ int x,y,mmin=1000000; for(int i=1;i<l;i++){ for(int j=i+1;j<l;j++){ if(e1[i][j]!=0&&e2[i][j]==0){ int i1=find(i); int j1=find(j); if(i1==j1) continue; int mmax=max(e1[0][i1],e1[0][j1]); if(mmin>(e1[i][j]-mmax)){ mmin=e1[i][j]-mmax; x=i; y=j; } } } } cnt--; e2[x][y]=1,e2[y][x]=1; int x1=find(x),y1=find(y); if(e1[0][x1]>e1[0][y1]) e1[0][x1]=e1[x1][0]=0,get(y1,x1); else e1[0][y1]=e1[y1][0]=0,get(x1,y1); } Print_ans();}void init(){ strcpy(name[0],"Park"); l=1; memset(e1,0,sizeof(e1)); memset(e2,0,sizeof(e2)); while(!q.empty()) q.pop(); for(int i=0;i<n;i++){ int w; scanf("%s%s%d",s1,s2,&w); int d1=get_id(s1); int d2=get_id(s2); q.push(Edge(d1,d2,w)); e1[d1][d2]=e1[d2][d1]=w; } scanf("%d",&k);}int main(){ while(scanf("%d",&n)!=EOF){ init(); solve(); }}
HDU 2121最小树形图(无固定根) http://acm.hdu.edu.cn/showproblem.php?pid=2121
#include <iostream>#include <cstdio>#include <cmath>#include <vector>#include <cstring>#include <algorithm>#include <string>#include <set>#include <ctime>#include <queue>#include <map>#include <sstream>#define CL(arr, val) memset(arr, val, sizeof(arr))#define REP(i, n) for((i) = 0; (i) < (n); ++(i))#define FOR(i, l, h) for((i) = (l); (i) <= (h); ++(i))#define FORD(i, h, l) for((i) = (h); (i) >= (l); --(i))#define L(x) (x) << 1#define R(x) (x) << 1 | 1#define MID(l, r) (l + r) >> 1#define Min(x, y) x < y ? x : y#define Max(x, y) x < y ? y : x#define E(x) (1 << (x))const double eps = 1e-6;const double inf = ~0u>>1;typedef long long LL;using namespace std;const int N = 1100; // 调整const int M = 20010; // 调整struct node { //可删 double x, y;} point[N];double SQ(int u, int v) { // 可删 return sqrt((point[u].x - point[v].x)*(point[u].x - point[v].x) + (point[u].y - point[v].y)*(point[u].y - point[v].y));}struct edg { int u, v; int cost; //double} E[M];int In[N]; //doubleint ID[N];int vis[N];int pre[N];int NV, NE; // n,m 0-->n-1 0-->m-1int Minroot;// 求入点int Directed_MST(int root) { //double int ret = 0; //double int i, u, v; while(true) { REP(i, NV) In[i] = inf; REP(i, NE) { //找最小入边 u = E[i].u; v = E[i].v; if(E[i].cost < In[v] && u != v) { In[v] = E[i].cost; if(u==root) Minroot=i; //求入口 pre[v] = u; } } REP(i, NV) { //如果存在除root以外的孤立点,则不存在最小树形图 if(i == root) continue; //printf("%.3lf ", In[i]); if(In[i] == inf) return -1; } int cnt = 0; CL(ID, -1); CL(vis, -1); In[root] = 0; REP(i, NV) { //找环 ret += In[i]; int v = i; while(vis[v] != i && ID[v] == -1 && v != root) { vis[v] = i; v = pre[v]; } if(v != root && ID[v] == -1) { //重新标号 for(u = pre[v]; u != v; u = pre[u]) { ID[u] = cnt; } ID[v] = cnt++; } } if(cnt == 0) break; REP(i, NV) { if(ID[i] == -1) ID[i] = cnt++; //重新标号 } REP(i, NE) { //更新其他点到环的距离 v = E[i].v; E[i].u = ID[E[i].u]; E[i].v = ID[E[i].v]; if(E[i].u != E[i].v) { E[i].cost -= In[v]; } } NV = cnt; root = ID[root]; } return ret;}int main() { while(scanf("%d%d",&NV,&NE)!=EOF) { int x=NE; for(int i=0;i<NE;i++) scanf("%d%d%d",&E[i].u,&E[i].v,&E[i].cost); for(int i=0;i<NV;i++){ E[NE].u=NV; E[NE].v=i; E[NE].cost=1e7; NE++; } NV++; int ans=Directed_MST(NV-1); ans-=1e7; if(ans>1e7) printf("impossible\n\n"); else printf("%d %d\n\n",ans,Minroot-x); // Minroot-x 入口 }}/*无固定根的最小树形图 Sample Input3 1 0 1 1 4 4 0 1 100 2 10 1 3 20 2 3 30 Sample Outputimpossible 40 0 // 40权值和 0 入口*/
0 0
- 生成树
- 生成树
- 生成树
- 生成树
- 生成树
- 最小生成生成树计数
- 生成树和生成森林
- 图 - 生成树和最小生成树 - 生成树
- 图 - 生成树和最小生成树 - 最小生成树
- 树-生成树-最小生成树
- 图--生成树和最小生成树
- 关于生成树 次小生成树
- 图---生成树与最小生成树
- 最小生成树-->次小生成树
- 最大生成树与最小生成树
- 生成树和最小生成树
- 最小生成树&&次小生成树
- 最小生成树,次小生成树
- 网站优化排名如何添加高质量的友情链接
- 在Ubuntu下构建Bullet以及运行Bullet的例子程序
- 跟着官方文档学HINT(二)优化器模式
- Oracle Database 9i/10g/11g编程艺术 笔记
- android自定义表格布局
- 生成树
- 黑马程序员-->Java基础-->数组
- 如何理解K线所包含的奥秘
- POJ 3630 --Trie
- QT Demo 之 MouseArea
- Dijkstra 最短路径算法的设计与PHP实现
- 拖延症的自白
- Linux的selinux
- 我的2014年10月