zoukankan      html  css  js  c++  java
  • 最小生成树

    poj1251 http://poj.org/problem?id=1251

    prim

     1 #include<cstdio>
     2 const int inf=0x3f3f3f3f;
     3 class Prim{///最小生成树(无向图)o(MV^2)要保证图连通
     4     typedef int typec;///边权的类型
     5     static const int MV=32;///点的个数
     6     int n,i,j,k,pre[MV];///pre[]返回树的构造,用父结点表示,根节点(第一个)pre值为-1
     7     bool vis[MV];
     8     typec mat[MV][MV],dist[MV],res;
     9 public:
    10     void init(int tn){///传入点数,点下标0开始
    11         n=tn;
    12         for(i=0;i<n;i++)
    13             for(j=0;j<n;j++)
    14                 mat[i][j]=i==j?0:inf;///不相邻点边权inf
    15     }
    16     void add(int u,int v,typec w){
    17         if(mat[u][v]>w){
    18             mat[u][v]=w;
    19             mat[v][u]=w;
    20         }
    21     }
    22     int solve(){///返回最小生成树的长度
    23         for(res=i=0;i<n;i++){
    24             dist[i]=inf;
    25             vis[i]=false;
    26             pre[i]=-1;
    27         }
    28         for(dist[j=0]=0;j<n;j++){
    29             for(k=-1,i=0;i<n;i++){
    30                 if(!vis[i]&&(k==-1||dist[i]<dist[k])){
    31                     k=i;
    32                 }
    33             }
    34             for(vis[k]=true,res+=dist[k],i=0;i<n;i++){
    35                 if(!vis[i]&&mat[k][i]<dist[i]){
    36                     dist[i]=mat[pre[i]=k][i];
    37                 }
    38             }
    39         }
    40         return res;
    41     }
    42 }gx;
    43 int main() {
    44     int n;
    45     char op[4];
    46     while(~scanf("%d",&n),n){
    47         gx.init(n);
    48         for(int i=0,num,val;i<n-1;i++){
    49             scanf("%s%d",op,&num);
    50             while(num--){
    51                 scanf("%s%d",op,&val);
    52                 gx.add(i,op[0]-'A',val);
    53                 gx.add(op[0]-'A',i,val);
    54             }
    55         }
    56         printf("%d
    ",gx.solve());
    57     }
    58     return 0;
    59 }
    View Code

    kruskal

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define mt(a,b) memset(a,b,sizeof(a))
     5 using namespace std;
     6 const int inf=0x3f3f3f3f;
     7 const int M=1010;
     8 class Kruskal { ///最小生成树(无向图)o(ME*logME)
     9     typedef int typec;///边权的类型
    10     static const int ME=1024;///边的个数
    11     static const int MV=32;///点的个数
    12     class UnionFindSet { ///并查集
    13         int par[MV];
    14     public:
    15         void init() {
    16             mt(par,-1);
    17         }
    18         int getroot(int x) {
    19             int i=x,j=x,temp;
    20             while(par[i]>=0) i=par[i];
    21             while(j!=i) {
    22                 temp=par[j];
    23                 par[j]=i;
    24                 j=temp;
    25             }
    26             return i;
    27         }
    28         bool unite(int x,int y) {
    29             int p=getroot(x);
    30             int q=getroot(y);
    31             if(p==q)return false;
    32             if(par[p]>par[q]) {
    33                 par[q]+=par[p];
    34                 par[p]=q;
    35             } else {
    36                 par[p]+=par[q];
    37                 par[q]=p;
    38             }
    39             return true;
    40         }
    41     } f;
    42     struct E {
    43         int u,v;
    44         typec w;
    45         friend bool operator < (E a,E b) {
    46             return a.w<b.w;
    47         }
    48     } e[ME];
    49     int le,num,n;
    50     typec res;
    51 public:
    52     void init(int tn){///传入点的个数
    53         n=tn;
    54         le=res=0;
    55         f.init();
    56         num=1;
    57     }
    58     void add(int u,int v,int w) {
    59         e[le].u=u;
    60         e[le].v=v;
    61         e[le].w=w;
    62         le++;
    63     }
    64     typec solve(){///返回-1不连通
    65         sort(e,e+le);
    66         for(int i=0; i<le&&num<n; i++) {
    67             if(f.unite(e[i].u,e[i].v)) {
    68                 num++;
    69                 res+=e[i].w;
    70             }
    71         }
    72         if(num<n) res=-1;
    73         return res;
    74     }
    75 }gx;
    76 int main() {
    77     int n;
    78     char op[4];
    79     while(~scanf("%d",&n),n) {
    80         gx.init(n);
    81         for(int i=0,num,val; i<n-1; i++) {
    82             scanf("%s%d",op,&num);
    83             while(num--) {
    84                 scanf("%s%d",op,&val);
    85                 gx.add(i,op[0]-'A',val);
    86             }
    87         }
    88         printf("%d
    ",gx.solve());
    89     }
    90     return 0;
    91 }
    View Code

    poj1258 http://poj.org/problem?id=1258

    prim

     1 #include<cstdio>
     2 const int inf=0x3f3f3f3f;
     3 class Prim { ///最小生成树(无向图)o(MV^2)要保证图连通
     4     typedef int typec;///边权的类型
     5     static const int MV=128;///点的个数
     6     int n,i,j,k,pre[MV];///pre[]返回树的构造,用父结点表示,根节点(第一个)pre值为-1
     7     bool vis[MV];
     8     typec mat[MV][MV],dist[MV],res;
     9 public:
    10     void init(int tn) { ///传入点数,点下标0开始
    11         n=tn;
    12         for(i=0; i<n; i++)
    13             for(j=0; j<n; j++)
    14                 mat[i][j]=i==j?0:inf;///不相邻点边权inf
    15     }
    16     void add(int u,int v,typec w) {
    17         if(mat[u][v]>w) {
    18             mat[u][v]=w;
    19             mat[v][u]=w;
    20         }
    21     }
    22     int solve() { ///返回最小生成树的长度
    23         for(res=i=0; i<n; i++) {
    24             dist[i]=inf;
    25             vis[i]=false;
    26             pre[i]=-1;
    27         }
    28         for(dist[j=0]=0; j<n; j++) {
    29             for(k=-1,i=0; i<n; i++) {
    30                 if(!vis[i]&&(k==-1||dist[i]<dist[k])) {
    31                     k=i;
    32                 }
    33             }
    34             for(vis[k]=true,res+=dist[k],i=0; i<n; i++) {
    35                 if(!vis[i]&&mat[k][i]<dist[i]) {
    36                     dist[i]=mat[pre[i]=k][i];
    37                 }
    38             }
    39         }
    40         return res;
    41     }
    42 }gx;
    43 int main(){
    44     int n;
    45     while(~scanf("%d",&n)){
    46         gx.init(n);
    47         for(int i=0,w;i<n;i++){
    48             for(int j=0;j<n;j++){
    49                 scanf("%d",&w);
    50                 gx.add(i,j,w);
    51             }
    52         }
    53         printf("%d
    ",gx.solve());
    54     }
    55     return 0;
    56 }
    View Code

    kruskal

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define mt(a,b) memset(a,b,sizeof(a))
     5 using namespace std;
     6 class Kruskal { ///最小生成树(无向图)o(ME*logME)
     7     typedef int typec;///边权的类型
     8     static const int ME=10010;///边的个数
     9     static const int MV=128;///点的个数
    10     class UnionFindSet { ///并查集
    11         int par[MV];
    12     public:
    13         void init() {
    14             mt(par,-1);
    15         }
    16         int getroot(int x) {
    17             int i=x,j=x,temp;
    18             while(par[i]>=0) i=par[i];
    19             while(j!=i) {
    20                 temp=par[j];
    21                 par[j]=i;
    22                 j=temp;
    23             }
    24             return i;
    25         }
    26         bool unite(int x,int y) {
    27             int p=getroot(x);
    28             int q=getroot(y);
    29             if(p==q)return false;
    30             if(par[p]>par[q]) {
    31                 par[q]+=par[p];
    32                 par[p]=q;
    33             } else {
    34                 par[p]+=par[q];
    35                 par[q]=p;
    36             }
    37             return true;
    38         }
    39     } f;
    40     struct E {
    41         int u,v;
    42         typec w;
    43         friend bool operator < (E a,E b) {
    44             return a.w<b.w;
    45         }
    46     } e[ME];
    47     int le,num,n;
    48     typec res;
    49 public:
    50     void init(int tn){///传入点的个数
    51         n=tn;
    52         le=res=0;
    53         f.init();
    54         num=1;
    55     }
    56     void add(int u,int v,typec w) {
    57         e[le].u=u;
    58         e[le].v=v;
    59         e[le].w=w;
    60         le++;
    61     }
    62     typec solve(){///返回-1不连通
    63         sort(e,e+le);
    64         for(int i=0; i<le&&num<n; i++) {
    65             if(f.unite(e[i].u,e[i].v)) {
    66                 num++;
    67                 res+=e[i].w;
    68             }
    69         }
    70         if(num<n) res=-1;
    71         return res;
    72     }
    73 }gx;
    74 int main(){
    75     int n;
    76     while(~scanf("%d",&n)){
    77         gx.init(n);
    78         for(int i=0,w;i<n;i++){
    79             for(int j=0;j<n;j++){
    80                 scanf("%d",&w);
    81                 if(i<j){
    82                     gx.add(i,j,w);
    83                 }
    84             }
    85         }
    86         printf("%d
    ",gx.solve());
    87     }
    88     return 0;
    89 }
    View Code

    poj1789 http://poj.org/problem?id=1789

    prim

     1 #include<cstdio>
     2 const int inf=0x3f3f3f3f;
     3 class Prim { ///最小生成树(无向图)o(MV^2)要保证图连通
     4     typedef int typec;///边权的类型
     5     static const int MV=2048;///点的个数
     6     int n,i,j,k,pre[MV];///pre[]返回树的构造,用父结点表示,根节点(第一个)pre值为-1
     7     bool vis[MV];
     8     typec mat[MV][MV],dist[MV],res;
     9 public:
    10     void init(int tn) { ///传入点数,点下标0开始
    11         n=tn;
    12         for(i=0; i<n; i++)
    13             for(j=0; j<n; j++)
    14                 mat[i][j]=i==j?0:inf;///不相邻点边权inf
    15     }
    16     void add(int u,int v,typec w) {
    17         if(mat[u][v]>w) {
    18             mat[u][v]=w;
    19             mat[v][u]=w;
    20         }
    21     }
    22     int solve() { ///返回最小生成树的长度
    23         for(res=i=0; i<n; i++) {
    24             dist[i]=inf;
    25             vis[i]=false;
    26             pre[i]=-1;
    27         }
    28         for(dist[j=0]=0; j<n; j++) {
    29             for(k=-1,i=0; i<n; i++) {
    30                 if(!vis[i]&&(k==-1||dist[i]<dist[k])) {
    31                     k=i;
    32                 }
    33             }
    34             for(vis[k]=true,res+=dist[k],i=0; i<n; i++) {
    35                 if(!vis[i]&&mat[k][i]<dist[i]) {
    36                     dist[i]=mat[pre[i]=k][i];
    37                 }
    38             }
    39         }
    40         return res;
    41     }
    42 }gx;
    43 struct S{
    44     char s[8];
    45 }str[2048];
    46 int main(){
    47     int n;
    48     while(~scanf("%d",&n),n){
    49         gx.init(n);
    50          for(int i=0;i<n;i++){
    51             scanf("%s",str[i].s);
    52         }
    53         for(int i=0;i<n;i++){
    54             for(int j=i+1;j<n;j++){
    55                 int val=0;
    56                 for(int k=0;k<7;k++){
    57                     if(str[i].s[k]!=str[j].s[k]){
    58                         val++;
    59                     }
    60                 }
    61                 gx.add(i,j,val);
    62             }
    63         }
    64         printf("The highest possible quality is 1/%d.
    ",gx.solve());
    65     }
    66     return 0;
    67 }
    View Code

    kruskal

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define mt(a,b) memset(a,b,sizeof(a))
     5 using namespace std;
     6 const int inf=0x3f3f3f3f;
     7 class Kruskal { ///最小生成树(无向图)o(ME*logME)
     8     typedef int typec;///边权的类型
     9     static const int ME=4000010;///边的个数
    10     static const int MV=2048;///点的个数
    11     class UnionFindSet { ///并查集
    12         int par[MV];
    13     public:
    14         void init() {
    15             mt(par,-1);
    16         }
    17         int getroot(int x) {
    18             int i=x,j=x,temp;
    19             while(par[i]>=0) i=par[i];
    20             while(j!=i) {
    21                 temp=par[j];
    22                 par[j]=i;
    23                 j=temp;
    24             }
    25             return i;
    26         }
    27         bool unite(int x,int y) {
    28             int p=getroot(x);
    29             int q=getroot(y);
    30             if(p==q)return false;
    31             if(par[p]>par[q]) {
    32                 par[q]+=par[p];
    33                 par[p]=q;
    34             } else {
    35                 par[p]+=par[q];
    36                 par[q]=p;
    37             }
    38             return true;
    39         }
    40     } f;
    41     struct E {
    42         int u,v;
    43         typec w;
    44         friend bool operator < (E a,E b) {
    45             return a.w<b.w;
    46         }
    47     } e[ME];
    48     int le,num,n;
    49     typec res;
    50 public:
    51     void init(int tn){///传入点的个数
    52         n=tn;
    53         le=res=0;
    54         f.init();
    55         num=1;
    56     }
    57     void add(int u,int v,typec w) {
    58         e[le].u=u;
    59         e[le].v=v;
    60         e[le].w=w;
    61         le++;
    62     }
    63     typec solve(){///返回-1不连通
    64         sort(e,e+le);
    65         for(int i=0; i<le&&num<n; i++) {
    66             if(f.unite(e[i].u,e[i].v)) {
    67                 num++;
    68                 res+=e[i].w;
    69             }
    70         }
    71         if(num<n) res=-1;
    72         return res;
    73     }
    74 }gx;
    75 struct S{
    76     char s[8];
    77 }str[2048];
    78 int main(){
    79     int n;
    80     while(~scanf("%d",&n),n){
    81         gx.init(n);
    82          for(int i=0;i<n;i++){
    83             scanf("%s",str[i].s);
    84         }
    85         for(int i=0;i<n;i++){
    86             for(int j=i+1;j<n;j++){
    87                 int val=0;
    88                 for(int k=0;k<7;k++){
    89                     if(str[i].s[k]!=str[j].s[k]){
    90                         val++;
    91                     }
    92                 }
    93                 gx.add(i,j,val);
    94             }
    95         }
    96         printf("The highest possible quality is 1/%d.
    ",gx.solve());
    97     }
    98     return 0;
    99 }
    View Code

     poj2349 http://poj.org/problem?id=2349

    prim

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<algorithm>
     4 using namespace std;
     5 const int inf=0x3f3f3f3f;
     6 class Prim { ///最小生成树(无向图)o(MV^2)要保证图连通
     7     typedef double typec;///边权的类型
     8     static const int MV=512;///点的个数
     9     int n,i,j,k,pre[MV];///pre[]返回树的构造,用父结点表示,根节点(第一个)pre值为-1
    10     bool vis[MV];
    11 public:
    12     typec mat[MV][MV],dist[MV],res;
    13 public:
    14     void init(int tn) { ///传入点数,点下标0开始
    15         n=tn;
    16         for(i=0; i<n; i++)
    17             for(j=0; j<n; j++)
    18                 mat[i][j]=i==j?0:inf;///不相邻点边权inf
    19     }
    20     void add(int u,int v,typec w) {
    21         if(mat[u][v]>w) {
    22             mat[u][v]=w;
    23             mat[v][u]=w;
    24         }
    25     }
    26     typec solve() { ///返回最小生成树的长度
    27         for(res=i=0; i<n; i++) {
    28             dist[i]=inf;
    29             vis[i]=false;
    30             pre[i]=-1;
    31         }
    32         for(dist[j=0]=0; j<n; j++) {
    33             for(k=-1,i=0; i<n; i++) {
    34                 if(!vis[i]&&(k==-1||dist[i]<dist[k])) {
    35                     k=i;
    36                 }
    37             }
    38             for(vis[k]=true,res+=dist[k],i=0; i<n; i++) {
    39                 if(!vis[i]&&mat[k][i]<dist[i]) {
    40                     dist[i]=mat[pre[i]=k][i];
    41                 }
    42             }
    43         }
    44         return res;
    45     }
    46 }gx;
    47 struct P{
    48     double x,y;
    49 }p[512];
    50 int main(){
    51     int t,n,m;
    52     while(~scanf("%d",&t)){
    53         while(t--){
    54             scanf("%d%d",&n,&m);
    55             for(int i=0;i<m;i++){
    56                 scanf("%lf%lf",&p[i].x,&p[i].y);
    57             }
    58             gx.init(m);
    59             for(int i=0;i<m;i++){
    60                 for(int j=0;j<m;j++){
    61                     gx.add(i,j,sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y)));
    62                 }
    63             }
    64             gx.solve();
    65             sort(gx.dist,gx.dist+m);
    66             printf("%.2f
    ",gx.dist[m-n]);
    67         }
    68     }
    69     return 0;
    70 }
    View Code

     kruskal

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cmath>
      4 #include<algorithm>
      5 #define mt(a,b) memset(a,b,sizeof(a))
      6 using namespace std;
      7 const int inf=0x3f3f3f3f;
      8 double d[250010];
      9 int ld;
     10 class Kruskal { ///最小生成树(无向图)o(ME*logME)
     11     typedef double typec;///边权的类型
     12     static const int ME=250010;///边的个数
     13     static const int MV=512;///点的个数
     14     class UnionFindSet { ///并查集
     15         int par[MV];
     16     public:
     17         void init() {
     18             mt(par,-1);
     19         }
     20         int getroot(int x) {
     21             int i=x,j=x,temp;
     22             while(par[i]>=0) i=par[i];
     23             while(j!=i) {
     24                 temp=par[j];
     25                 par[j]=i;
     26                 j=temp;
     27             }
     28             return i;
     29         }
     30         bool unite(int x,int y) {
     31             int p=getroot(x);
     32             int q=getroot(y);
     33             if(p==q)return false;
     34             if(par[p]>par[q]) {
     35                 par[q]+=par[p];
     36                 par[p]=q;
     37             } else {
     38                 par[p]+=par[q];
     39                 par[q]=p;
     40             }
     41             return true;
     42         }
     43     } f;
     44     struct E {
     45         int u,v;
     46         typec w;
     47         friend bool operator < (E a,E b) {
     48             return a.w<b.w;
     49         }
     50     } e[ME];
     51     int le,num,n;
     52     typec res;
     53 public:
     54     void init(int tn){///传入点的个数
     55         n=tn;
     56         le=res=0;
     57         f.init();
     58         num=1;
     59     }
     60     void add(int u,int v,typec w) {
     61         e[le].u=u;
     62         e[le].v=v;
     63         e[le].w=w;
     64         le++;
     65     }
     66     typec solve(){///返回-1不连通
     67         sort(e,e+le);
     68         for(int i=0; i<le&&num<n; i++) {
     69             if(f.unite(e[i].u,e[i].v)) {
     70                 num++;
     71                 res+=e[i].w;
     72                 d[ld++]=e[i].w;
     73             }
     74         }
     75         if(num<n) res=-1;
     76         return res;
     77     }
     78 }gx;
     79 struct P{
     80     double x,y;
     81 }p[512];
     82 int main(){
     83     int t,n,m;
     84     while(~scanf("%d",&t)){
     85         while(t--){
     86             scanf("%d%d",&n,&m);
     87             for(int i=0;i<m;i++){
     88                 scanf("%lf%lf",&p[i].x,&p[i].y);
     89             }
     90             gx.init(m);
     91             for(int i=0;i<m;i++){
     92                 for(int j=i+1;j<m;j++){
     93                     gx.add(i,j,sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y)));
     94                 }
     95             }
     96             ld=0;
     97             gx.solve();
     98             sort(d,d+ld);
     99             printf("%.2f
    ",d[m-n-1]);
    100         }
    101     }
    102     return 0;
    103 }
    View Code

     poj2485 http://poj.org/problem?id=2485

    prim

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 const int inf=0x3f3f3f3f;
     5 class Prim { ///最小生成树(无向图)o(MV^2)要保证图连通
     6     typedef int typec;///边权的类型
     7     static const int MV=512;///点的个数
     8     int n,i,j,k,pre[MV];///pre[]返回树的构造,用父结点表示,根节点(第一个)pre值为-1
     9     bool vis[MV];
    10 public:
    11     typec mat[MV][MV],dist[MV],res;
    12 public:
    13     void init(int tn) { ///传入点数,点下标0开始
    14         n=tn;
    15         for(i=0; i<n; i++)
    16             for(j=0; j<n; j++)
    17                 mat[i][j]=i==j?0:inf;///不相邻点边权inf
    18     }
    19     void add(int u,int v,typec w) {
    20         if(mat[u][v]>w) {
    21             mat[u][v]=w;
    22             mat[v][u]=w;
    23         }
    24     }
    25     typec solve() { ///返回最小生成树的长度
    26         for(res=i=0; i<n; i++) {
    27             dist[i]=inf;
    28             vis[i]=false;
    29             pre[i]=-1;
    30         }
    31         for(dist[j=0]=0; j<n; j++) {
    32             for(k=-1,i=0; i<n; i++) {
    33                 if(!vis[i]&&(k==-1||dist[i]<dist[k])) {
    34                     k=i;
    35                 }
    36             }
    37             for(vis[k]=true,res+=dist[k],i=0; i<n; i++) {
    38                 if(!vis[i]&&mat[k][i]<dist[i]) {
    39                     dist[i]=mat[pre[i]=k][i];
    40                 }
    41             }
    42         }
    43         return res;
    44     }
    45 }gx;
    46 int main(){
    47     int t,n;
    48     while(~scanf("%d",&t)){
    49         while(t--){
    50             scanf("%d",&n);
    51             gx.init(n);
    52             for(int i=0,w;i<n;i++){
    53                 for(int j=0;j<n;j++){
    54                     scanf("%d",&w);
    55                     gx.add(i,j,w);
    56                 }
    57             }
    58             gx.solve();
    59             int ans=0;
    60             for(int i=1;i<n;i++){
    61                 ans=max(ans,gx.dist[i]);
    62             }
    63             printf("%d
    ",ans);
    64         }
    65     }
    66     return 0;
    67 }
    View Code

    kruskal

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define mt(a,b) memset(a,b,sizeof(a))
     5 using namespace std;
     6 const int inf=0x3f3f3f3f;
     7 int ans;
     8 class Kruskal { ///最小生成树(无向图)o(ME*logME)
     9     typedef int typec;///边权的类型
    10     static const int ME=250010;///边的个数
    11     static const int MV=512;///点的个数
    12     class UnionFindSet { ///并查集
    13         int par[MV];
    14     public:
    15         void init() {
    16             mt(par,-1);
    17         }
    18         int getroot(int x) {
    19             int i=x,j=x,temp;
    20             while(par[i]>=0) i=par[i];
    21             while(j!=i) {
    22                 temp=par[j];
    23                 par[j]=i;
    24                 j=temp;
    25             }
    26             return i;
    27         }
    28         bool unite(int x,int y) {
    29             int p=getroot(x);
    30             int q=getroot(y);
    31             if(p==q)return false;
    32             if(par[p]>par[q]) {
    33                 par[q]+=par[p];
    34                 par[p]=q;
    35             } else {
    36                 par[p]+=par[q];
    37                 par[q]=p;
    38             }
    39             return true;
    40         }
    41     } f;
    42     struct E {
    43         int u,v;
    44         typec w;
    45         friend bool operator < (E a,E b) {
    46             return a.w<b.w;
    47         }
    48     } e[ME];
    49     int le,num,n;
    50     typec res;
    51 public:
    52     void init(int tn){///传入点的个数
    53         n=tn;
    54         le=res=0;
    55         f.init();
    56         num=1;
    57     }
    58     void add(int u,int v,typec w) {
    59         e[le].u=u;
    60         e[le].v=v;
    61         e[le].w=w;
    62         le++;
    63     }
    64     typec solve(){///返回-1不连通
    65         sort(e,e+le);
    66         for(int i=0; i<le&&num<n; i++) {
    67             if(f.unite(e[i].u,e[i].v)) {
    68                 num++;
    69                 res+=e[i].w;
    70                 ans=max(ans,e[i].w);
    71             }
    72         }
    73         if(num<n) res=-1;
    74         return res;
    75     }
    76 }gx;
    77 int main(){
    78     int t,n;
    79     while(~scanf("%d",&t)){
    80         while(t--){
    81             scanf("%d",&n);
    82             gx.init(n);
    83             for(int i=0,w;i<n;i++){
    84                 for(int j=0;j<n;j++){
    85                     scanf("%d",&w);
    86                     if(i<j)
    87                         gx.add(i,j,w);
    88                 }
    89             }
    90             ans=0;
    91             gx.solve();
    92             printf("%d
    ",ans);
    93         }
    94     }
    95     return 0;
    96 }
    View Code

     poj3026 http://poj.org/problem?id=3026

    prim

      1 #include<cstdio>
      2 #include<queue>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define mt(a,b) memset(a,b,sizeof(a))
      6 using namespace std;
      7 const int inf=0x3f3f3f3f;
      8 const int M=2024;
      9 int n,m;
     10 struct P{
     11     int x,y;
     12 }p[M*M];
     13 char a[M][M];
     14 int num[M][M];
     15 int cost[M][M];
     16 bool ispoint(char c){
     17     if(c=='S'||c=='A') return true;return false;
     18 }
     19 struct Q{
     20     int x,y,id,step;
     21 }pre,now;
     22 queue<Q> q;
     23 int dx[]={0,0,1,-1};
     24 int dy[]={1,-1,0,0};
     25 bool vis[M][M];
     26 void bfs(Q now){
     27     mt(vis,0);
     28     while(!q.empty()) q.pop();
     29     q.push(now);
     30     vis[now.x][now.y]=true;
     31     while(!q.empty()){
     32         pre=q.front();
     33         q.pop();
     34         if(ispoint(a[pre.x][pre.y])){
     35             if(cost[pre.id][num[pre.x][pre.y]]>pre.step)
     36                 cost[pre.id][num[pre.x][pre.y]]=pre.step;
     37         }
     38         for(int i=0;i<4;i++){
     39             int tx=pre.x+dx[i];
     40             int ty=pre.y+dy[i];
     41             if(tx>=0&&tx<n&&ty>=0&&ty<m&&a[tx][ty]!='#'&&!vis[tx][ty]){
     42                 vis[tx][ty]=true;
     43                 now.x=tx;
     44                 now.y=ty;
     45                 now.id=pre.id;
     46                 now.step=pre.step+1;
     47                 q.push(now);
     48             }
     49         }
     50     }
     51 }
     52 class Prim { ///最小生成树(无向图)o(MV^2)要保证图连通
     53     typedef int typec;///边权的类型
     54     static const int MV=M;///点的个数
     55     int n,i,j,k,pre[MV];///pre[]返回树的构造,用父结点表示,根节点(第一个)pre值为-1
     56     bool vis[MV];
     57     typec mat[MV][MV],dist[MV],res;
     58 public:
     59     void init(int tn) { ///传入点数,点下标0开始
     60         n=tn;
     61         for(i=0; i<n; i++)
     62             for(j=0; j<n; j++)
     63                 mat[i][j]=i==j?0:inf;///不相邻点边权inf
     64     }
     65     void add(int u,int v,typec w) {
     66         if(mat[u][v]>w) {
     67             mat[u][v]=w;
     68             mat[v][u]=w;
     69         }
     70     }
     71     typec solve() { ///返回最小生成树的长度
     72         for(res=i=0; i<n; i++) {
     73             dist[i]=inf;
     74             vis[i]=false;
     75             pre[i]=-1;
     76         }
     77         for(dist[j=0]=0; j<n; j++) {
     78             for(k=-1,i=0; i<n; i++) {
     79                 if(!vis[i]&&(k==-1||dist[i]<dist[k])) {
     80                     k=i;
     81                 }
     82             }
     83             for(vis[k]=true,res+=dist[k],i=0; i<n; i++) {
     84                 if(!vis[i]&&mat[k][i]<dist[i]) {
     85                     dist[i]=mat[pre[i]=k][i];
     86                 }
     87             }
     88         }
     89         return res;
     90     }
     91 }gx;
     92 int main(){
     93     int t;
     94     while(~scanf("%d",&t)){
     95         while(t--){
     96             scanf("%d%d",&m,&n);
     97             while(getchar()==' ') getchar();
     98             for(int i=0;i<n;i++){
     99                 gets(a[i]);
    100             }
    101             int lp=0;
    102             for(int i=0;i<n;i++){
    103                 for(int j=0;j<m;j++){
    104                     if(ispoint(a[i][j])){
    105                         num[i][j]=lp;
    106                         p[lp].x=i;
    107                         p[lp].y=j;
    108                         lp++;
    109                     }
    110                     else{
    111                         num[i][j]=-1;
    112                     }
    113                 }
    114             }
    115             for(int i=0;i<lp;i++){
    116                 for(int j=0;j<lp;j++){
    117                     cost[i][j]=inf;
    118                 }
    119                 cost[i][i]=0;
    120             }
    121             for(int i=0;i<lp;i++){
    122                 now.x=p[i].x;
    123                 now.y=p[i].y;
    124                 now.id=i;
    125                 now.step=0;
    126                 bfs(now);
    127             }
    128             gx.init(lp);
    129             for(int i=0;i<lp;i++){
    130                 for(int j=0;j<lp;j++){
    131                     gx.add(i,j,cost[i][j]);
    132                 }
    133             }
    134             printf("%d
    ",gx.solve());
    135         }
    136     }
    137     return 0;
    138 }
    View Code

     kruskal

      1 #include<cstdio>
      2 #include<queue>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define mt(a,b) memset(a,b,sizeof(a))
      6 using namespace std;
      7 const int inf=0x3f3f3f3f;
      8 const int M=2024;
      9 int n,m;
     10 struct P{
     11     int x,y;
     12 }p[M*M];
     13 char a[M][M];
     14 int num[M][M];
     15 int cost[M][M];
     16 bool ispoint(char c){
     17     if(c=='S'||c=='A') return true;return false;
     18 }
     19 struct Q{
     20     int x,y,id,step;
     21 }pre,now;
     22 queue<Q> q;
     23 int dx[]={0,0,1,-1};
     24 int dy[]={1,-1,0,0};
     25 bool vis[M][M];
     26 void bfs(Q now){
     27     mt(vis,0);
     28     while(!q.empty()) q.pop();
     29     q.push(now);
     30     vis[now.x][now.y]=true;
     31     while(!q.empty()){
     32         pre=q.front();
     33         q.pop();
     34         if(ispoint(a[pre.x][pre.y])){
     35             if(cost[pre.id][num[pre.x][pre.y]]>pre.step)
     36                 cost[pre.id][num[pre.x][pre.y]]=pre.step;
     37         }
     38         for(int i=0;i<4;i++){
     39             int tx=pre.x+dx[i];
     40             int ty=pre.y+dy[i];
     41             if(tx>=0&&tx<n&&ty>=0&&ty<m&&a[tx][ty]!='#'&&!vis[tx][ty]){
     42                 vis[tx][ty]=true;
     43                 now.x=tx;
     44                 now.y=ty;
     45                 now.id=pre.id;
     46                 now.step=pre.step+1;
     47                 q.push(now);
     48             }
     49         }
     50     }
     51 }
     52 class Kruskal { ///最小生成树(无向图)o(ME*logME)
     53     typedef int typec;///边权的类型
     54     static const int ME=M*M;///边的个数
     55     static const int MV=M;///点的个数
     56     class UnionFindSet { ///并查集
     57         int par[MV];
     58     public:
     59         void init() {
     60             mt(par,-1);
     61         }
     62         int getroot(int x) {
     63             int i=x,j=x,temp;
     64             while(par[i]>=0) i=par[i];
     65             while(j!=i) {
     66                 temp=par[j];
     67                 par[j]=i;
     68                 j=temp;
     69             }
     70             return i;
     71         }
     72         bool unite(int x,int y) {
     73             int p=getroot(x);
     74             int q=getroot(y);
     75             if(p==q)return false;
     76             if(par[p]>par[q]) {
     77                 par[q]+=par[p];
     78                 par[p]=q;
     79             } else {
     80                 par[p]+=par[q];
     81                 par[q]=p;
     82             }
     83             return true;
     84         }
     85     } f;
     86     struct E {
     87         int u,v;
     88         typec w;
     89         friend bool operator < (E a,E b) {
     90             return a.w<b.w;
     91         }
     92     } e[ME];
     93     int le,num,n;
     94     typec res;
     95 public:
     96     void init(int tn){///传入点的个数
     97         n=tn;
     98         le=res=0;
     99         f.init();
    100         num=1;
    101     }
    102     void add(int u,int v,typec w) {
    103         e[le].u=u;
    104         e[le].v=v;
    105         e[le].w=w;
    106         le++;
    107     }
    108     typec solve(){///返回-1不连通
    109         sort(e,e+le);
    110         for(int i=0; i<le&&num<n; i++) {
    111             if(f.unite(e[i].u,e[i].v)) {
    112                 num++;
    113                 res+=e[i].w;
    114             }
    115         }
    116         if(num<n) res=-1;
    117         return res;
    118     }
    119 }gx;
    120 int main(){
    121     int t;
    122     while(~scanf("%d",&t)){
    123         while(t--){
    124             scanf("%d%d",&m,&n);
    125             while(getchar()==' ') getchar();
    126             for(int i=0;i<n;i++){
    127                 gets(a[i]);
    128             }
    129             int lp=0;
    130             for(int i=0;i<n;i++){
    131                 for(int j=0;j<m;j++){
    132                     if(ispoint(a[i][j])){
    133                         num[i][j]=lp;
    134                         p[lp].x=i;
    135                         p[lp].y=j;
    136                         lp++;
    137                     }
    138                     else{
    139                         num[i][j]=-1;
    140                     }
    141                 }
    142             }
    143             for(int i=0;i<lp;i++){
    144                 for(int j=0;j<lp;j++){
    145                     cost[i][j]=inf;
    146                 }
    147                 cost[i][i]=0;
    148             }
    149             for(int i=0;i<lp;i++){
    150                 now.x=p[i].x;
    151                 now.y=p[i].y;
    152                 now.id=i;
    153                 now.step=0;
    154                 bfs(now);
    155             }
    156             gx.init(lp);
    157             for(int i=0;i<lp;i++){
    158                 for(int j=i+1;j<lp;j++){
    159                     gx.add(i,j,cost[i][j]);
    160                 }
    161             }
    162             printf("%d
    ",gx.solve());
    163         }
    164     }
    165     return 0;
    166 }
    View Code

    end

  • 相关阅读:
    谈谈我的经历--【产品设计中遇到的坑0】系列文章的序
    2017.02.04,读书,2017第二本《把时间当作朋友》读书笔记
    读书《重生,七年就是一辈子》
    好剧推荐:This is us
    直播预告:产品设计中不得不知的事情
    高德地图事件与插件绑定
    高德地图基础
    es6 Iterator和for...of循环
    class与class的继承
    JS保留两位小数的几种方法
  • 原文地址:https://www.cnblogs.com/gaolzzxin/p/3944320.html
Copyright © 2011-2022 走看看