POJ1062——昂贵的聘礼

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 using namespace std;
 6 const int N = 100+10;
 7 int n,m;
 8 int le[N],w[N];
 9 int g[N][N];
10 int dis[N],vis[N];
11 void Dijkstra(int l,int r)
12 {
13     memset(dis,0x1f,sizeof dis);  //由于要多次调用,故需注意初始化
14     memset(vis,0,sizeof vis);
15     dis[n+1]=0;
16     for(int i=1;i<=n;i++)
17     {
18         int min_len=2e+9,k;
19         for(int j=1;j<=n+1;j++)
20         {
21             if(le[j]<l||le[j]>r)continue;  //保证在区间以内
22             if(!vis[j]&&dis[j]<min_len)
23             {
24                 min_len=dis[j];
25                 k=j;
26             }
27         }
28         vis[k]=1;
29         for(int j=1;j<=n+1;j++)
30         {
31             if(le[j]<l||le[j]>r)continue;  //保证在区间以内
32             if(g[k][j]&&!vis[j]&&dis[j]>dis[k]+g[k][j])
33             {
34                 dis[j]=dis[k]+g[k][j];
35             }
36         }
37     }
38 }
39 
40 int main()
41 {
42     scanf("%d%d",&m,&n);
43     for(int i=1;i<=n;i++)
44     {
45         int p,l,x;
46         scanf("%d%d%d",&p,&l,&x);le[i]=l;w[i]=p;
47         for(int j=1;j<=x;j++)
48         {
49             int a,b;scanf("%d%d",&a,&b);
50             g[a][i]=b;  //邻接矩阵建图
51         }
52     }
53     
54     for(int i=1;i<=n;i++)g[n+1][i]=w[i];  //本算法精髓所在:建立虚拟源点,该点出发到其余个点的边权均为该点所代表的的物品的价格。
55     le[n+1]=le[1];
56 
57     int i=le[1]-m;  //处理区间边缘
58     if(i<=0)i=1;
59   
60     int minn=2e+9;
61     for(int j=i+m;j<=le[1]+m;i++,j++)  //枚举区间,调用Dijkstra
62     {
63         Dijkstra(i,j);
64         minn=min(minn,dis[1]);
65     }
66     printf("%d\n",minn);
67     return 0;
68 }

 

posted @ 2019-07-19 08:53  魑吻丶殇之玖梦  阅读(70)  评论(0编辑  收藏  举报