hdu 2988 Dark roads

这题一看数据,m,n都是十万级别的..顿时迷茫了....

百度了一下,看到列表里面有kruscal算法,就想着试一下..没想到过了..真的不是数据太水吗..

计算机1秒能算十亿次(这个是从别人博客上学习来的);

200000^2 好像有点大,就没敢用prim算法来算..所以没写..毕竟prim要查找,差不多是n^2复杂度..

上网搜了一下,竟然有一个人,还是唯一一个人用了prim..贴上代码膜拜一下;

kruscal一般在稀疏图的时候使用,比较快,稀疏图是个叫法吧,没有太确定的界限..不过N*(N-1)/2肯定是稠密图,用prim肯定比kruscal快的..

下面这个是自己写的kruscal算法.

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 using namespace std;
 6 #define maxn 200005
 7 #define INF 0x3f3f3f3f
 8 int father[maxn];
 9 int n ,m;
10 struct node{
11     int u , v;
12     int w;
13 }edge[maxn];
14 void init()
15 {
16     for(int i = 0 ;i <= n ;i++)
17         father[i] = i;
18 }
19 int find(int x)
20 {
21     if(father[x]==x)
22         return x;
23     return father[x]=find(father[x]);
24 }
25 void unite(int x,int y)
26 {
27     int fx = find(x) , fy = find(y);
28     if(fx == fy)
29         return ;
30     father[fy] = fx;
31 }
32 bool cmp(node a , node b)
33 {
34     return a.w < b.w;
35 }
36 int kruscal(int t)
37 {
38     int res = 0,count = 0;
39     int u,v;
40     for(int i = 0 ;i < t; i++)
41     {
42         u = edge[i].u;
43         v = edge[i].v;
44         if(find(u)!=find(v))
45         {
46             unite(u,v);
47             count++;
48             res += edge[i].w;
49 
50         }
51 
52     }
53     return res;
54 }
55 int main()
56 {
57     //freopen("2988.txt","r",stdin);
58     int a,b,d,total;
59     while(~scanf("%d %d",&m,&n)&&(m||n))
60     {
61         total = 0;
62         init();
63         for(int i = 0 ; i< n ; i++)
64         {
65             scanf("%d %d %d",&a,&b,&d);
66             edge[i].u = a ;
67             edge[i].v = b;
68             edge[i].w = d;
69             total += d;
70         }
71         sort(edge,edge+n,cmp);
72         int sum = kruscal(n);
73         printf("%d\n",total-sum);
74     }
75     return 0;
76 }
View Code


下面这个是网上大牛用prim写的..两种算法都是700ms级别的,后面这个算法稍微慢一点;

 1 #include<iostream>
 2 using namespace std;
 3 
 4 struct Edge{
 5  int l,r,w;
 6  int next;
 7 };
 8 int head[200001];
 9 Edge edges[400001];
10 int dis[200001];
11 bool visit[200001];
12 int n,m;
13 int loc;
14 
15 void addEdge(int l,int r,int w){
16  edges[loc].l=l,edges[loc].r=r,edges[loc].w=w,edges[loc].next=head[l],head[l]=loc++;
17 }
18 
19 int prim(){
20  int out=0;
21  memset(dis,-1,sizeof(dis));
22  memset(visit,false,sizeof(visit));
23  dis[0]=0;
24  int i;
25  for(i=1;i<=n;i++){
26   int sm=INT_MAX;
27   int id;
28   int j;
29   for(j=0;j<n;j++){
30    if(dis[j]<sm&&!visit[j]&&dis[j]!=-1){
31     sm=dis[j];
32     id=j;
33    }
34   }
35   out+=dis[id];
36   visit[id]=true;
37   for(j=head[id];j!=-1;j=edges[j].next){
38    if(dis[edges[j].r]==-1||edges[j].w<dis[edges[j].r]){
39     dis[edges[j].r]=edges[j].w;
40    }
41   }
42   
43  }
44  return out;
45 }
46 
47 
48 
49 int main(){
50  //freopen("a.txt","r",stdin);
51  while(scanf("%d%d",&n,&m)!=EOF){
52   int all=0;
53   if(n==0&&m==0){
54    break;
55   }
56   loc=0;
57   memset(head,-1,sizeof(head));
58   
59   int i;
60   for(i=1;i<=m;i++){
61    int a,b,c;
62    scanf("%d%d%d",&a,&b,&c);
63    addEdge(a,b,c);
64    addEdge(b,a,c);
65    all+=c;
66   }
67   printf("%d\n",all-prim());
68  }
69 
70 
71  return 0;
72 }
View Code

 

转载于:https://www.cnblogs.com/xiaoniuniu/p/4392865.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值