zoukankan      html  css  js  c++  java
  • POJ 3164最小树形图

      1 /*POJ 3164
      2 一个通信网络被破坏了
      3 给定每个点的坐标,和两两之间可修复的边和长度
      4 现在选择部分修通,使从1点出发可到达所有点,并且代价最短
      5 
      6 可看出是一个生成树的问题,做了UVA的那道,这道很简单了
      7 
      8 PS:unidirection 是有向
      9    undirecttion 才是无向
     10 C++交才可以
     11 */
     12 #include<iostream>
     13 #include<string.h>
     14 #include<stdio.h>
     15 #include<stdlib.h>
     16 #include<cmath>
     17 #include<algorithm>
     18 #include<queue>
     19 #include<stack>
     20 #include<set>
     21 #include<map>
     22 #define maxn 100+5
     23 #define maxe 20000+5
     24 #define typec double
     25 using namespace std;
     26 
     27 const typec inf=99999999;
     28 int nextint(){int x;scanf("%d",&x);return x;}
     29 int nextdou(){double x;scanf("%lf",&x);return x;}
     30 double X[maxn],Y[maxn];
     31 double Dis(int i,int j){
     32     double x1=X[i],x2=X[j],y1=Y[i],y2=Y[j];
     33     return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
     34 }
     35 struct Edge{
     36     int u,v;
     37     typec c;//权值
     38 }edge[maxe];
     39 
     40 int vis[maxn],pre[maxn],id[maxn];
     41 typec in[maxn];
     42 typec zhuliu(int root,int nv,int ne){//最小树形图
     43       int i,j,u,v;
     44       typec ans=0;
     45       while(1){
     46               for(i=0;i<nv;i++)in[i]=inf;
     47               for(i=0;i<ne;i++){
     48                       u=edge[i].u;
     49                       v=edge[i].v;
     50                       if(u!=v&&edge[i].c<in[v]){
     51                               pre[v]=u;
     52                               in[v]=edge[i].c;
     53                       }
     54               }
     55               in[root]=0;
     56               for(i=0;i<nv;i++)if(fabs(in[i]-inf)<1e-6)return -1;
     57               int cnt=0;
     58               memset(id,-1,sizeof(id));
     59               memset(vis,-1,sizeof(vis));
     60               for(i=0;i<nv;i++){
     61                       v=i;
     62                       ans+=in[i];
     63                       while(vis[v]!=i&&id[v]==-1&&v!=root){
     64                               vis[v]=i;
     65                               v=pre[v];
     66                       }
     67                       if(v!=root&&id[v]==-1){
     68                               for(u=pre[v];u!=v;u=pre[u])id[u]=cnt;
     69                               id[v]=cnt++;
     70                       }
     71               }
     72               if(cnt==0)break;
     73               for(i=0;i<nv;i++)if(id[i]==-1)id[i]=cnt++;
     74               for(i=0;i<ne;i++){
     75                       v=edge[i].v;
     76                       edge[i].u=id[edge[i].u];
     77                       edge[i].v=id[edge[i].v];
     78                       if(edge[i].u!=edge[i].v)edge[i].c-=in[v];
     79               }
     80               nv=cnt;root=id[root];
     81       }
     82         return ans;
     83 }
     84 int n,m;
     85 int cnt;
     86 void built_tree(){
     87     cnt=0;
     88     for(int i=0;i<m;i++){
     89         int u=nextint(),v=nextint();
     90         u--,v--;
     91         double dis=Dis(u,v);
     92 //        cout<<u<<","<<v<<" dis="<<dis<<endl;
     93         edge[cnt].u=u;
     94         edge[cnt].v=v;
     95         edge[cnt++].c=dis;
     96 //        edge[cnt++]=(Edge){v,u,dis};
     97     }
     98 }
     99 int main(){
    100 //    freopen("out.txt","w",stdout);
    101     while(cin>>n>>m){
    102         for (int i=0;i<n;i++){
    103             X[i]=nextdou();
    104             Y[i]=nextdou();
    105         }
    106         built_tree();
    107         double ans=zhuliu(0,n,cnt);
    108         if (ans<0) printf("poor snoopy
    ");else printf("%.2lf
    ",ans);
    109     }
    110     return 0;
    111 }
  • 相关阅读:
    【c语言】使用NULL和指针来寻找数组中是否存在指定的数字
    【c语言】利用指针求三个数的最大数和最小数
    【c语言】统计一个整数所包含的素因子并输出
    【c语言】比较两个分数的大小
    心情
    matlab
    越来越懒了
    研究生学习
    谢谢
    elasticsearch 索引
  • 原文地址:https://www.cnblogs.com/little-w/p/3597094.html
Copyright © 2011-2022 走看看