nkoj 2226
一道很好的图论dijstra算法应用题。
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; const int inf=2e9; queue<int>q; int m,n,pos[105],dist[105],map[105][105]; bool vis[105]; void input(){ int i,j,x,y,t; scanf("%d%d",&m,&n); for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(i!=j)map[i][j]=inf; for(i=1;i<=n;i++){ //每件物品 scanf("%d%d%d",&t,&pos[i],&x); map[0][i]=t; while(x--){ //优惠 scanf("%d%d",&y,&t); map[y][i]=t; } } } int dijstra(int minn,int maxx){ //枚举地位从minn到maxx的人 int i,x; memset(vis,0,sizeof(vis)); //别忘了清零 for(i=1;i<=n;i++)dist[i]=map[0][i]; dist[0]=0;vis[0]=true; do{ int k=inf; x=0; for(i=1;i<=n;i++) if(!vis[i]&&dist[i]<k&&pos[i]>=minn&&pos[i]<=maxx) //条件:地位适合 k=dist[i],x=i; if(x>0){ vis[x]=true; for(i=1;i<=n;i++) dist[i]=min(dist[i],dist[x]+map[x][i]); //更新dist } }while(x>0); return dist[1]; } void solve(){ int ans=map[0][1]; for(int i=pos[1]-m;i<=pos[1];i++) //依次枚举每个区间 ans=min(dijstra(i,i+m),ans); printf("%d",ans); } int main(){ input(); solve(); }