POJ-3164- Command Network(最小树形图)
2017-02-21 14:38
387 查看
题目链接:POJ-3164- Command Network
最小树形图的算法:
1. 找出除根之外每个点的
2. 检测图中是否有环,若无环,则已经找到最小树形图。若有环,则将环染色缩点,若u与v在同一个环中,中,那么 id[u]==id[v] 。
3. 缩点,对于边 (u,v,d) ,将其转化为 (id[u],id[v],d−in[v]) 。
4. 重复上面三步,每一步res+=除根之外所有的
为什么新入边权值要减去
在每一步由所有的
具体可以看最小树形图 。
最小树形图的算法:
1. 找出除根之外每个点的
in[i],
in[i]表示点i所有入边的最小值。
2. 检测图中是否有环,若无环,则已经找到最小树形图。若有环,则将环染色缩点,若u与v在同一个环中,中,那么 id[u]==id[v] 。
3. 缩点,对于边 (u,v,d) ,将其转化为 (id[u],id[v],d−in[v]) 。
4. 重复上面三步,每一步res+=除根之外所有的
in[i]。
为什么新入边权值要减去
in[v]?
在每一步由所有的
in[i]生成的图中,若存在环,则必然没有没有边指向这个环。要让这个环消失,则必然要在这个环中删去一边,并在这个环外选取一边指向环,假设我们选取一个指向 u 的边作为新边,则必然要删去
in[u],因此将所有指向 u 的边减去
in[u],这样在之后的步骤中,选取了新边,则自然删去了环中对应的边。
具体可以看最小树形图 。
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define mp make_pair #define pr pair<int,int> #define fi fisr using namespace std; typedef long long ll; const double INF=1e10; struct Edge { int u,v; double d; }; int n,m; int vis[107],id[107],pre[107]; Edge edges[10007]; double in[107],x[107],y[107]; double zhuliu(int rt) { double res=0; while(1) { //1.找最小入边 for(int i=1;i<=n;i++) in[i]=INF; for(int i=0;i<m;i++) { int u=edges[i].u,v=edges[i].v; if(edges[i].d<in[v]&&u!=v) //忽略重边,因为重边不影响最小树形图 in[v]=edges[i].d,pre[v]=u; } for(int i=1;i<=n;i++) if(i!=rt&&in[i]==INF) //若一点与图不连通,则不存在最小树形图 return INF; //2.找环 int tn=0; memset(vis,-1,sizeof(vis)); memset(id,-1,sizeof(id)); in[rt]=0; for(int i=1;i<=n;i++) { res+=in[i]; int u=i; //找环 while(u!=rt&&id[u]==-1&&vis[u]!=i) { vis[u]=i; u=pre[u]; } //染色 if(u!=rt&&id[u]==-1) { id[u]=++tn; for(int v=pre[u];v!=u;v=pre[v]) id[v]=tn; } } if(tn==0) break; //不发现环,则是最小树形图,返回 //将不在环中的点染色 for(int i=1;i<=n;i++) if(id[i]==-1) id[i]=++tn; //3.缩点 for(int i=0;i<m;) { int u=edges[i].u,v=edges[i].v; edges[i].u=id[u]; edges[i].v=id[v]; if(edges[i].u!=edges[i].v) edges[i++].d-=in[v]; else edges[i]=edges[--m]; } n=tn; rt=id[rt]; f923 } return res; } int main() { while(~scanf("%d%d",&n,&m)) { int u,v; for(int i=1;i<=n;i++) scanf("%lf%lf",&x[i],&y[i]); for(int i=0;i<m;i++) { scanf("%d%d",&u,&v); edges[i].u=u;edges[i].v=v; edges[i].d=sqrt(pow(x[u]-x[v],2)+pow(y[u]-y[v],2)); } double ans=zhuliu(1); if(ans==INF) puts("poor snoopy"); else printf("%.2f\n",ans); } return 0; }
相关文章推荐
- Command Network POJ - 3164(根为1的最小树形图)
- POJ 3164 Command Network(最小树形图)
- POJ 3164——Command Network——————【最小树形图、固定根】
- POJ 3164 Command Network (最小树形图-朱刘算法)
- 最小树形图 Command Network POJ - 3164
- 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 (最小树形图模板,3级)
- poj 3164 Command Network(最小树形图模板题)
- POJ-3164 Command Network 最小树形图
- POJ 3164 Command Network(最小树形图)
- POJ 3164:Command Network(最小树形图)
- POJ 3164 Command Network(最小树形图模板)
- POJ 3164 Command Network (最小树形图模板,3级)
- POJ 3164 Command Network 最小树形图模板 朱-刘算法