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 }