码迷,mamicode.com
首页 > 其他好文 > 详细

图论相关

时间:2017-11-08 00:47:50      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:博客   html   道路   之间   one   tps   amp   cin   ati   

 

最小生成树:

 

畅通工程

HDU - 1232
 
只要互相间接通过道路可达即可,说明只要最后是一棵树就可以. 树的边数为顶点数减1.
用并查集求出当前已有的边数, 再用 n-1减去就是还需要再建的路.
技术分享
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<string>
 6 using namespace std;
 7 const int maxn=1010;
 8 int f[maxn];
 9 int n,m;
10 void init()
11 {
12     for(int i=0;i<=n;i++)
13         f[i]=i;
14 }
15 int  gf(int x)
16 {
17     return x==f[x]?x:f[x]=gf(f[x]);
18 }
19 void unit(int x,int y)
20 {
21     int px=gf(x);
22     int py=gf(y);
23     f[px]=py;
24 }
25 
26 int main()
27 {
28     while(cin>>n&&n)
29     {
30         cin>>m;
31         int cnt=0;
32         init();
33         int x,y;
34         for(int i=0;i<m;i++){
35             cin>>x>>y;
36                 if(gf(x)!=gf(y)) {unit(x,y);cnt++;}
37         }
38         cout<<n-1-cnt<<endl;
39     }
40 }
View Code

 


还是畅通工程

HDU - 1233
和ppt上讲的一样,就是最小生成树的模板题, 先对边进行排序, 然后用并查集维护一下,就可以了.
 
技术分享
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 using namespace std;
 5 int f[105];
 6    int n;
 7 struct Edge
 8 {
 9     int x,y,w;
10     bool operator <(const Edge &a)const
11     {
12         return w<a.w;
13     }
14 }e[10010];
15 void init()
16 {
17     for(int i=0;i<=n;i++)
18         f[i]=i;
19 }
20 int  gf(int x)
21 {
22     return x==f[x]?x:f[x]=gf(f[x]);
23 }
24 void unit(int x,int y)
25 {
26     int px=gf(x);
27     int py=gf(y);
28     f[px]=py;
29 }
30 
31 int main()
32 {
33 
34     while(cin>>n&&n)
35     {
36         init();
37         int cnt=0;
38         int ans=0;
39         int m=n*(n-1)/2;
40         for(int i=0;i<m;i++)
41             cin>>e[i].x>>e[i].y>>e[i].w;
42         sort(e,e+m);
43         for(int i=0;i<m;i++)
44         {
45             if(gf(e[i].x)!=gf(e[i].y)) {
46                     ans+=e[i].w;
47                     unit(e[i].x,e[i].y);
48                     cnt++;
49             }
50             if(cnt==n-1) break;    //已经是树, 跳出循环
51         }
52         cout<<ans<<endl;
53 
54     }
55 }
View Code

 

 

 

Building a Space Station

POJ - 2031
 

求出任意两点之间的距离减去两个点的半径。

然后求最小生成树.

技术分享
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=110;
 7 int n;
 8 int f[maxn];
 9 struct node
10 {
11     double x,y,z;
12     double r;
13 }p[maxn];
14 
15 struct edge
16 {
17     int u,v;
18     double w;
19     bool operator < (const edge &a)
20     {
21         return w<a.w;
22     }
23 }e[100010];
24 
25 double getdis(int  i,int j)
26 {
27     double dx=p[i].x-p[j].x;
28     double dy=p[i].y-p[j].y;
29     double dz=p[i].z-p[j].z;
30     return sqrt(dx*dx+dy*dy+dz*dz)-p[i].r-p[j].r;
31 }
32 
33 void init()
34 {
35     for(int i=0;i<n;i++)
36         f[i]=i;
37 }
38 
39 int gf(int a)
40 {
41     return a==f[a]?a:f[a]=gf(f[a]);
42 }
43 
44 void uni(int a,int b)
45 {
46     int pa=gf(a);
47     int pb=gf(b);
48     f[pb]=pa;
49 }
50 
51 int main()
52 {
53     while(scanf("%d",&n)&&n)
54     {
55         init();
56         for(int i=0;i<n;i++)
57         {
58             scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z,&p[i].r);
59         }
60         int cnt=0;
61         for(int i=0;i<n;i++)
62             for(int j=i+1;j<n;j++)
63         {
64             e[cnt].u=i;
65             e[cnt].v=j;
66             e[cnt].w=getdis(i,j);
67             cnt++;
68         }
69         double ans=0;
70         sort(e,e+cnt);
71         for(int i=0;i<cnt;i++)
72         {
73             if(e[i].w<=0) uni(e[i].u,e[i].v);
74           else   if(gf(e[i].u)!=gf(e[i].v))  {ans+=e[i].w; uni(e[i].u,e[i].v);}
75         }
76         printf("%.3f\n",ans);
77     }
78 }
View Code

 

最短路:

有选择的看一下这篇博客:  链接

 

图论相关

标签:博客   html   道路   之间   one   tps   amp   cin   ati   

原文地址:http://www.cnblogs.com/yijiull/p/7801922.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!