POJ 3164 Command Network(最小树形图)
2013-01-05 23:26
465 查看
题目链接:http://poj.org/problem?id=3164
题意:给定一个图,求最小树形图。1为根节点。
思路:求以root为根的最小树形图(假设图中每个点均可由root到达):
(1)为每个顶点找一条权值最小的入边;
(2)此时如不存在环,结束;否则转(3);
(3)将环缩成一个点new;对于环中的每个点u,环中u的入边权值为x,对于边<u,i,dis>(i不在环中),增加边<new,i,dis>;对于边<i,u,dis>(i不在环中),增加边<i,new,dis-x>(显然你选择了这条边那么之前指向u的边就会删掉)。
(4)重复(1)到(3)直到结束。
题意:给定一个图,求最小树形图。1为根节点。
思路:求以root为根的最小树形图(假设图中每个点均可由root到达):
(1)为每个顶点找一条权值最小的入边;
(2)此时如不存在环,结束;否则转(3);
(3)将环缩成一个点new;对于环中的每个点u,环中u的入边权值为x,对于边<u,i,dis>(i不在环中),增加边<new,i,dis>;对于边<i,u,dis>(i不在环中),增加边<i,new,dis-x>(显然你选择了这条边那么之前指向u的边就会删掉)。
(4)重复(1)到(3)直到结束。
#include <iostream> #include <cmath> #include <stdio.h> #include <string.h> #define min(x,y) ((x)<(y)?(x):(y)) using namespace std; struct Point { int x,y; }; const double INF=1000000000.0; Point p[105]; double map[105][105],ans; int n,m,father[105],visit[105],flag[105]; double Dis(Point a,Point b) { return sqrt(0.0+(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } void DFS(int u) { int v; visit[u]=1; for(v=1;v<=n;v++) if(!visit[v]&&map[u][v]<INF) DFS(v); } int connet() { memset(visit,0,sizeof(visit)); DFS(1); for(int i=1;i<=n;i++) if(!visit[i]) return 0; return 1; } int exist_circle() { int i,j; father[1]=1; for(i=2;i<=n;i++) if(!flag[i]) { father[i]=i; map[i][i]=INF; for(j=1;j<=n;j++) if(!flag[j]&&map[j][i]<map[father[i]][i]) father[i]=j; } for(i=2;i<=n;i++) if(!flag[i]) { for(j=1;j<=n;j++) visit[j]=0; for(j=i;!visit[j];j=father[j]) visit[j]=1; if(j!=1) return j; } return -1; } void update(int t) { int i,j; ans+=map[father[t]][t]; for(i=father[t];i!=t;i=father[i]) { ans+=map[father[i]][i]; flag[i]=1; } for(i=1;i<=n;i++) if(!flag[i]&&map[i][t]<INF) map[i][t]-=map[father[t]][t]; for(i=father[t];i!=t;i=father[i]) for(j=1;j<=n;j++) if(!flag[j]) { if(map[j][i]<INF) map[j][t]=min(map[j][t],map[j][i]-map[father[i]][i]); map[t][j]=min(map[t][j],map[i][j]); } } double solve() { int i; memset(flag,0,sizeof(flag)); ans=0.0; while((i=exist_circle())!=-1) update(i); for(i=2;i<=n;i++) if(!flag[i]) ans+=map[father[i]][i]; return ans; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { int i,j,u,v; for(i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y); for(i=1;i<=n;i++) for(j=1;j<=n;j++) map[i][j]=INF; for(i=1;i<=m;i++) { scanf("%d%d",&u,&v); map[u][v]=Dis(p[u],p[v]); } if(!connet()) puts("poor snoopy"); else printf("%.2lf\n",solve()); } return 0; }
相关文章推荐
- poj 3164 Command Network#有向最小树形图
- POJ 3164 Command Network 最小树形图
- poj 3164 Command Network(最小树形图—朱刘算法模版)
- POJ 3164 Command Network(最小树形图模板题)
- 【poj 3164】Command Network 最小树形图
- POJ 3164 Command Network【最小树形图】
- POJ 3164 Command Network 最小树形图 模板题
- POJ 3164 Command Network(最小树形图模板题)
- POJ 3164 Command Network (最小树形图)
- POJ 3164 Command Network(最小树形图+朱刘算法)
- POJ-3164 Command Network (最小树形图)
- 【POJ】3164 Command Network 最小树形图——朱刘算法
- POJ 3164 Command Network(最小树形图)
- POJ-3164- Command Network(最小树形图)
- poj 3164 Command Network(最小树形图模板)
- poj 3164 Command Network(最小树形图模板题)朱_ 刘算法
- POJ 3164 Command Network 最小树形图模板题
- POJ 3164 Command Network 最小树形图
- [POJ 3164]Command Network[最小树形图]
- POJ 3164:Command Network(最小树形图)