题目链接:http://poj.org/problem?id=1062
好不容看到一道中文题..很激动但还是看不懂啊,感觉中文题反而更难了....
这题是最短路的问题,discuss里也有DFS爆搜做的,没仔细看,题目很经典。
感觉建立图论模型真的异常艰难。
这道题的难点在于如何建立Dijsktra算法模型,假定增加一个起点0,到终点1,共有N个点,经过其中n个点,要求按照等级从小向上,且等级差不超过m,枚举每个点,求出最短路径。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; const int INF=0x3f3f3f3f; const int maxn=110; int n,m; int edge[maxn][maxn];//i点到j点的边权 int level[maxn];//第i个点的等级 int price[maxn];//第i个点的价格 int dis[maxn];//到源点的距离 bool vis[maxn]; void Init(){ memset(price,0,sizeof(price)); memset(level,0,sizeof(level)); memset(vis,0,sizeof(vis)); memset(edge,0x3f,sizeof(edge)); } int Dijsktra(){ for(int i=1;i<=n;i++)//初始化源点到任一点的距离为当前价格 dis[i]=price[i]; for(int i=1;i<=n;i++){ int x,min=INF; for(int j=1;j<=n;j++){ if(!vis[j]&&dis[j]<min){ min=dis[x=j]; } } vis[x]=1; for(int j=1;j<=n;j++){ if(!vis[j]&&dis[j]>dis[x]+edge[x][j]) dis[j]=dis[x]+edge[x][j]; } } return dis[1]; } int main(){ #ifndef ONLINE_JUDGE freopen("test.in","r",stdin); freopen("test.out","w",stdout); #endif while(~scanf("%d%d",&m,&n)){ Init(); int t,v,w; for(int i=1;i<=n;i++){ scanf("%d%d%d",&price[i],&level[i],&t); while(t--){ scanf("%d%d",&v,&w); edge[v][i]=w; } edge[0][i]=price[i]; } int res=INF; for(int i=1;i<=n;i++){ int minLevel=level[i];//视当前点的等级为最低等级 for(int j=1;j<=n;j++){ if(level[j]-minLevel>m||level[j]<minLevel) vis[j]=1; else vis[j]=0; } int ans=Dijsktra(); res=min(res,ans); } printf("%d\n",res); } return 0; }