• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
mengxm
博客园    首页    新随笔    联系   管理    订阅  订阅

poj1797

本人一直比较愚钝,所以做题之时只有多花时间,此题是dijkstra变形,网上较多代码却少有解释为什么,我为何我一样的菜鸟来解释一下吧。

首先你要明白dijkstra之所以能用贪心的原因,不明者可以看dijkstra,bellman-ford,floyd分析比较 也就是dist[i]在证明中表示原点到i的最短路径,显然此题的dist表示原点到i的路径中最大载重量,为什么dist也可以表示?,当dist[i]被选中时不会改变了吗?它就是最大载重吗?

如s->t最大载重是10,s->i->t最大载重是20,可能是t在i之前被选中吗?答案是不可能,若s->i->t最大载重是20那么该路上所有边都>=20也就意味着i必然先于t被选择,那么就保证了贪心的正确性,所以此题可用dijkstra。

View Code
 1 #include <stdio.h>
2 #include <string.h>
3 #define MAXN 1001
4 #define MIN(a,b) ((a)?((a)<(b)?(a):(b)):(b))
5 #define INF (1<<29)
6 struct node
7 {
8 int d,w;
9 node* next;
10 };
11 node *head[MAXN],edge[MAXN*MAXN],*p;
12 bool v[MAXN];
13 int n,m,max[MAXN];
14 void dij()
15 {
16 for(int i=1;i<=n;max[i++]=0);
17 int t=1,f=0;
18 while(f!=-1)
19 {
20 f=-1;
21 for(int i=1;i<=n;++i)
22 if(!v[i]&&f<max[i])
23 f=max[i],t=i;
24 v[t]=true;
25 for(p=head[t];p;p=p->next)
26 if(!v[p->d]&&max[p->d]<MIN(max[t],p->w))
27 max[p->d]=MIN(max[t],p->w);
28 }
29 }
30 int main()
31 {
32 int num;
33 scanf("%d",&num);
34 for(int k=1;k<=num;++k)
35 {
36 p=edge;
37 memset(head,NULL,sizeof(head));
38 memset(v,false,sizeof(v));
39 scanf("%d %d",&n,&m);
40 for(int i=0,a,b,c;i<m;++i)
41 {
42 scanf("%d %d %d",&a,&b,&c);
43 p->d=b;
44 p->w=c;
45 p->next=head[a];
46 head[a]=p++;
47 p->d=a;
48 p->w=c;
49 p->next=head[b];
50 head[b]=p++;
51 }
52 dij();
53 printf("Scenario #%d:\n%d\n",k,max[n]);
54 printf("\n");
55 }
56 return 0;
57 }



posted @ 2012-02-13 22:59  mengxm  阅读(278)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3