首页 > 代码库 > 【POJ】【3164】Commond Network

【POJ】【3164】Commond Network

最小树形图

  最小树形图模板题,朱-刘算法。

  题解:http://blog.csdn.net/shuangde800/article/details/8039359

  这位大神代码写的非常通俗易懂,而且这种代码风格也很值得学习……面向对象?= =听说这样封装起来可以避免using namespace std;出现的奇葩错误

 

写错的地方:一开始找最小前驱边的时候 把 “!inc[i]"的叹号丢了……

技术分享
  1 //POJ 3164  2 #include<cmath>  3 #include<cstdio>  4 #include<cstring>  5 #include<cstdlib>  6 #include<iostream>  7 #include<algorithm>  8 #define rep(i,n) for(int i=0;i<n;++i)  9 #define F(i,j,n) for(int i=j;i<=n;++i) 10 #define D(i,j,n) for(int i=j;i>=n;--i) 11 using namespace std; 12 void read(int &v){ 13     v=0; int sign=1; char ch=getchar(); 14     while(ch<0||ch>9){ if (ch==-) sign=-1; ch=getchar();} 15     while(ch>=0&&ch<=9){ v=v*10+ch-0; ch=getchar();} 16     v*=sign; 17 } 18 /******************tamplate*********************/ 19 const int N=110; 20 const int INF=~0u>>2; 21 template<typename Type> 22 class Directed_MST{ 23     public: 24     void init(int _n){ 25         n=_n; 26         ans=0; 27         memset(vis,0,sizeof vis); 28         memset(inc,0,sizeof inc); 29         F(i,0,n){ 30             w[i][i]=INF; 31             F(j,i+1,n) w[i][j]=w[j][i]=INF; 32         } 33     } 34     void insert(int x,int y,Type _w){ 35         if (w[x][y]>_w) w[x][y]=_w; 36     } 37     Type directed_mst(int x){ 38 #ifdef debug 39         F(i,1,n){ 40             F(j,1,n)  41                 if (w[i][j]==INF) printf(" INF "); 42                 else printf("%.2f ",w[i][j]); 43             printf("\n"); 44         } 45 #endif 46         // step1 判断能否形成最小树形图,直接dfs遍历 47         dfs(x); 48         F(i,1,n) if(!vis[i]) return -1; 49          50         // 如果可以形成最小树形图,继续 51         // step2 52         memset(vis,0,sizeof vis); 53         while(1){ 54             //1.找最小前驱边 55             F(i,1,n) if (i!=x && !inc[i]){ 56                 w[i][i]=INF, pre[i]=i; 57                 F(j,1,n)  58                     if(!inc[j] && w[j][i]<w[pre[i]][i]) 59                         pre[i]=j; 60             } 61             //2.判断是否有环 62             int i; 63             for(i=1;i<=n;++i) if (i!=x && !inc[i]){ 64                 int j=i,cnt=0; 65                 while(j!=x && pre[j]!=i && cnt<=n) j=pre[j],++cnt; 66                 if (j==x || cnt>n) continue; 67                 break; 68             } 69                  70             //没有找到环,找到答案 71             if (i>n){ 72                 F(i,1,n) 73                     if (i!=x && !inc[i]) ans+=w[pre[i]][i]; 74                 return ans; 75             } 76             //有环,进行收缩 77             int j=i; 78             memset(vis,0,sizeof vis); 79             do{ 80                 ans+=w[pre[j]][j],j=pre[j],vis[j]=inc[j]=true; 81             }while(j!=i); 82             inc[i]=false;//!!!!环缩成了点i,点i依然存在 83              84             //收缩 85             F(k,1,n) if(vis[k]) 86                 F(j,1,n) if(!vis[j]){ 87                     if (w[i][j]>w[k][j]) w[i][j]=w[k][j]; 88                     if (w[j][k]<INF && w[j][k]-w[pre[k]][k] < w[j][i]) 89                         w[j][i]=w[j][k]-w[pre[k]][k]; 90                 } 91         } 92         return ans; 93     } 94  95     private: 96     void dfs(int x){ 97         vis[x]=1; 98         F(i,1,n) if (!vis[i] && w[x][i]<INF) 99             dfs(i);100     }101     private:102     Type ans;103     int n;104     int pre[N];105     bool vis[N],inc[N];106     Type w[N][N];107 };108 struct node{109     double x,y;110     double operator - (const node&now)const{111         return sqrt( (x-now.x)*(x-now.x)+(y-now.y)*(y-now.y) );112     }113 }a[N];114 115 Directed_MST<double>G;116 117 int main(){118     int n,m,x,y;119     while(scanf("%d%d",&n,&m)!=EOF){120         G.init(n);121         F(i,1,n) scanf("%lf%lf",&a[i].x,&a[i].y);122         123         F(i,1,m){124             scanf("%d%d",&x,&y);125             if (x==y) continue;126             G.insert(x,y,a[x]-a[y]);127         }128         double ans=G.directed_mst(1);129         if (ans<0) puts("poor snoopy");130         else printf("%.2f\n",ans);131     }132     return 0;133 }
View Code

 

【POJ】【3164】Commond Network