poj1062

转自:http://blog.sina.com.cn/s/blog_676070110100mjya.html

 1 题意:昂贵的聘礼,好题!!!
 2 算法:分两步:1、建图 2、从底到上逐个求每个点的最小费用。具体实现见程序注释。
 3 #include <iostream>
 4 using namespace std;
 5 const int MAX=120;
 6 int M,N,X,T,V;  //等级限制    物品总数       替代品总数        替代品的编号   优惠价格
 7 int map[MAX][MAX];   //初始化全为0    map[i][j]=-1:i和j不能交换物品     map[i][j]=t:物品i可以用物品j加t金币替换
 8 int topo[MAX];   //对于处理完的图,从底向上编号   topo[i]=j:第t个物品的编号为j
 9 int visted[MAX];  //访问数组,初始化为0
10 //物品结构体
11 typedef struct NODE
12 {
13  int level;  //等级
14  int price;  //价格
15 }NODE;
16 NODE nodes[MAX];
17 int num=0;  //物品从底向上的序号,具体Topo函数
18 //采用深度优先的方式,对物品从底向上编号
19 void Dfs(int v)
20 {
21  visted[v]=1;
22  for (int i=1;i<=N;i++)
23  {
24   // 如果i未访问过 && u、i连通
25   if (!visted[i] && map[v][i]>0)
26   {
27    Dfs(i);
28   }
29  }
30  topo[num++]=v;
31 }
32 //计算完物品的编号后,从底向上计算物品的最小花费
33 void MinCost()
34 {
35  int i,j;
36  for (i=0;i<N;i++)
37  {
38   for (j=i+1;j<N;j++)
39   {   
40    //以下的关系,要画个图,看清谁指向谁
41    if (map[topo[j]][topo[i]]>0)
42    {
43     int temp=nodes[topo[i]].price+map[topo[j]][topo[i]];
44     if ((temp<nodes[topo[j]].price))
45     {
46      nodes[topo[j]].price=temp;
47     }
48    }
49   }
50  }
51  printf("%d\n",nodes[1].price);
52 }
53 int main()
54 {
55  int i,j;
56  memset(map,0,sizeof(map));
57  memset(visted,0,sizeof(visted));
58  scanf("%d%d",&M,&N);   //等级限制    物品总数
59  for (i=1;i<=N;i++)
60  {
61   scanf("%d%d%d",&nodes[i].price,&nodes[i].level,&X);  //价格 主人的地位等级 替代品总数
62   for (j=1;j<=X;j++)
63   {
64    scanf("%d%d",&T,&V);  //替代品的编号   优惠价格
65    map[i][T]=V;
66   }
67   //如果物品i不能和物品1交换,那么物品i可以直接不考虑:即便倒贴钱,也不能和物品1交换。直接把它加入黑名单
68   if( abs(nodes[i].level-nodes[1].level) > M )
69         {
70    //把物品i加入黑名单:置物品i不能和任何物品交换
71             for(j=1;j<N;j++)
72    {
73     map[j][i]=-1;
74    }
75         }
76  } 
77  Dfs(1);  //从1开始,从底向上编号
78  MinCost();  //求每个物品的最小花费
79  return 0;
80 }

自己模仿写后的代码,以及其中的一些细节和思考

 1 #include <iostream>
 2 #include <stdlib.h>
 3 using namespace std;
 4 
 5 struct node
 6 {
 7     int price;
 8     int level;
 9 };
10 node a[105];
11 int map[105][105];
12 int m,n;
13 int visited [105];
14 int search_result[105];
15 int num=0;
16 
17 
18 void dfs(int v)//完成深度优先遍历
19 {
20 
21     int i;
22 
23     visited[v]=1;
24     for(i=0;i<n;i++)
25     {
26         if(visited[i]==0 && map[v][i]>0)
27         {
28             dfs(i);
29         }
30     }
31     search_result[num++]=v;
32     //cout<<"search_result[]"<<num-1<<search_result[num-1]<<endl;
33 }
34 
35 
36 
37 int MinCost()
38 {
39     int i,j;
40     int tmp;
41     for(i=0;i<n;i++)
42     {
43         for(j=i+1;j<n;j++)
44         {
45             if(map[search_result[j]][search_result[i]]>0)
46             {
47                 tmp=a[search_result[i]].price+map[search_result[j]][search_result[i]];
48                 if(tmp<a[search_result[j]].price)
49                 {
50                     a[search_result[j]].price=tmp;
51                 }
52 
53             }
54         }
55     }
56     return a[0].price;
57 }
58 int main()
59 {
60     int i,j;
61     cin>>m>>n;
62     int x;
63     int t,v;
64     for(i=0;i<n;i++)//注意这里是从一开始还是从零开始    //处理输入问题
65     {
66         cin>>a[i].price>>a[i].level>>x;
67         for(j=0;j<x;j++)
68         {
69             cin>>t>>v;
70             map[i][t-1]=v;//注意这里是t-1,主要是因为题意给的是物品从一开始编号,而我自己写的是从零开始编号
71         }
72 
73 
74         if(abs(a[i].level-a[0].level)>m)//这里解决等级的问题
75         {
76             for(j=0;j<n;j++)//注意这里不能改为j=i+1,因为虽有可能编号靠后,但深度搜索的时候在哪个位置不太确定
77             {
78                 map[j][i]=-1;
79             }
80         }
81     }
82     dfs(0);
83     cout<<MinCost()<<endl;
84     return 0;
85 }

 

 

posted on 2012-08-04 09:15  矮人狙击手!  阅读(315)  评论(0编辑  收藏  举报

导航